On Tue, 2011-01-04 at 15:51 +0900, Itagaki Takahiro wrote:
> On Tue, Dec 28, 2010 at 22:17, Magnus Hagander <mag...@hagander.net> wrote:
> >>> We definitely need the very basic level for 9.1, and we can always
> >>> improve on it later :-)
> >
> >>> pg_stat_walsender. It would then only need the columns for procpid,
> >>> usesysid, usename, client_addr, client_port, and the WALsender
> >>> specific fields.
> > Yeah, agreed. backend_start is probably the best one
> 
> Here are patches for pg_stat_walsender.
> I split the feature into two pieces:
> 
> * get_host_and_port.patch
> It separates host and port formatter as a subroutine from pg_stat_activity.
> In addition, make pg_stat_get_backend_client_addr/port() functions to
> use the subroutine to reduce duplicated codes.
> 
> * pg_stat_walsender.patch
> It adds pg_stat_walsender system view. It has subset columns of
> pg_stat_activity and only one additional WAL sender specific information
> via WALSndStatus(). I named the column "sending location" because
> standby servers might not have received the WAL record; if we had
> synchronous replication, a new "sent location" wold be added.
> But the naming is still an open question. Comments welcome.
> 
> There is O(max_wal_senders^2) complexity in the view, But I think
> it is not so serious problem because we can expect max_wal_senders
> is 10 or so at most.
> 
> CREATE VIEW pg_stat_walsender AS
>     SELECT
>             S.procpid,
>             S.usesysid,
>             U.rolname AS usename,
>             S.client_addr,
>             S.client_port,
>             S.backend_start,
>             S.xlog_sending
>     FROM pg_stat_get_walsender(NULL) AS S, pg_authid U
>     WHERE S.usesysid = U.oid;

Just seen you started working on this again. Very good.

I enclose some snippets of code I was working on, which I am removing
from my patch in favour of your work as a separate commit.

The way I coded it was a new SRF that joins to the existing
pg_stat_activity. So no initdb required, and this can also easily be
included as an external module for 9.0.

Please notice also that my coding of the new SRF does not have the O^2
issue you mention, which I was keen to avoid.

The sent pointer is needed whether or not we have sync rep. We should
also include application name, since the user may set that in the
standby for all the same reasons it is set elsewhere.

Small point: please lets not call this pg_stat_walsender?
pg_stat_replication_sent and pg_stat_replication_received would be
easier for normal humans to understand.

I would very much appreciate it if one of you could complete something
here and commit in the next few days. That would then allow me to extend
the view with sync rep specific info for monitoring and patch testing.

-- 
 Simon Riggs           http://www.2ndQuadrant.com/books/
 PostgreSQL Development, 24x7 Support, Training and Services
 
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 346eaaf..75419b7 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -488,6 +488,21 @@ CREATE VIEW pg_stat_activity AS
     WHERE S.datid = D.oid AND
             S.usesysid = U.oid;
 
+CREATE VIEW pg_stat_replication_activity AS
+    SELECT
+            S.procpid,
+            S.usesysid,
+            U.rolname AS usename,
+            S.application_name,
+            S.client_addr,
+            S.client_port,
+            S.backend_start,
+            R.sent_location
+    FROM pg_stat_get_activity(NULL) AS S, pg_authid U,
+            pg_stat_get_replication_activity() AS R
+    WHERE S.usesysid = U.oid AND
+            S.procpid = R.procpid;
+
 CREATE VIEW pg_stat_database AS
     SELECT
             D.oid AS datid,
diff --git a/src/backend/replication/walsender.c b/src/backend/replication/walsender.c
index e9d8847..4422f5a 100644
--- a/src/backend/replication/walsender.c
+++ b/src/backend/replication/walsender.c
@@ -37,6 +37,7 @@
 #include <signal.h>
 #include <unistd.h>
 
+#include "funcapi.h"
 #include "access/xlog_internal.h"
 #include "catalog/pg_type.h"
 #include "libpq/libpq.h"
@@ -49,6 +50,7 @@
 #include "storage/ipc.h"
 #include "storage/pmsignal.h"
 #include "tcop/tcopprot.h"
+#include "utils/builtins.h"
 #include "utils/guc.h"
 #include "utils/memutils.h"
 #include "utils/ps_status.h"
@@ -1122,6 +1124,91 @@ WalSndWakeup(void)
 }
 
 /*
+ * Returns the Send position of walsenders with given pid.
+ * Or InvalidXLogRecPtr if none.
+ */
+Datum
+pg_stat_get_replication_activity(PG_FUNCTION_ARGS)
+{
+	FuncCallContext *funcctx;
+
+	if (SRF_IS_FIRSTCALL())
+	{
+		MemoryContext oldcontext;
+		TupleDesc	tupdesc;
+
+		funcctx = SRF_FIRSTCALL_INIT();
+
+		oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
+
+#define PG_STAT_GET_REP_ACTIVITY_COLS 	2
+		tupdesc = CreateTemplateTupleDesc(PG_STAT_GET_REP_ACTIVITY_COLS, false);
+		TupleDescInitEntry(tupdesc, (AttrNumber) 1, "procpid", INT4OID, -1, 0);
+		TupleDescInitEntry(tupdesc, (AttrNumber) 2, "sent_location", TEXTOID, -1, 0);
+
+		funcctx->tuple_desc = BlessTupleDesc(tupdesc);
+
+		funcctx->user_fctx = palloc0(sizeof(int));
+		if (superuser())
+			funcctx->max_calls = max_wal_senders;
+		else
+			funcctx->max_calls = 0;
+
+		MemoryContextSwitchTo(oldcontext);
+	}
+
+	/* stuff done on every call of the function */
+	funcctx = SRF_PERCALL_SETUP();
+
+	if (funcctx->call_cntr < funcctx->max_calls)
+	{
+		/* for each row */
+		Datum		values[PG_STAT_GET_REP_ACTIVITY_COLS];
+		bool		nulls[PG_STAT_GET_REP_ACTIVITY_COLS];
+		HeapTuple	tuple;
+
+		MemSet(values, 0, sizeof(values));
+		MemSet(nulls, 0, sizeof(nulls));
+
+		{
+			/* use volatile pointer to prevent code rearrangement */
+			volatile WalSnd *walsnd = &WalSndCtl->walsnds[funcctx->call_cntr];
+			char		sendlocation[MAXFNAMELEN];
+			XLogRecPtr	recptr;
+
+			if (walsnd->pid == 0)
+			{
+				nulls[0] = true;
+				nulls[1] = true;
+			}
+			else
+			{
+				SpinLockAcquire(&walsnd->mutex);
+				recptr = walsnd->sentPtr;
+				SpinLockRelease(&walsnd->mutex);
+
+				snprintf(sendlocation, sizeof(sendlocation), "%X/%X",
+						 recptr.xlogid, recptr.xrecoff);
+
+				nulls[0] = false;
+				values[0] = Int32GetDatum(walsnd->pid);
+
+				nulls[1] = false;
+				values[1] = CStringGetTextDatum(sendlocation);
+			}
+
+			tuple = heap_form_tuple(funcctx->tuple_desc, values, nulls);
+			SRF_RETURN_NEXT(funcctx, HeapTupleGetDatum(tuple));
+		}
+	}
+	else
+	{
+		/* nothing left */
+		SRF_RETURN_DONE(funcctx);
+	}
+}
+
+/*
  * This isn't currently used for anything. Monitoring tools might be
  * interested in the future, and we'll need something like this in the
  * future for synchronous replication.
diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h
index 1e6e75f..3218b87 100644
--- a/src/include/catalog/pg_proc.h
+++ b/src/include/catalog/pg_proc.h
@@ -3067,6 +3067,8 @@ DATA(insert OID = 1936 (  pg_stat_get_backend_idset		PGNSP PGUID 12 1 100 0 f f
 DESCR("statistics: currently active backend IDs");
 DATA(insert OID = 2022 (  pg_stat_get_activity			PGNSP PGUID 12 1 100 0 f f f f t s 1 0 2249 "23" "{23,26,23,26,25,25,16,1184,1184,1184,869,23}" "{i,o,o,o,o,o,o,o,o,o,o,o}" "{pid,datid,procpid,usesysid,application_name,current_query,waiting,xact_start,query_start,backend_start,client_addr,client_port}" _null_ pg_stat_get_activity _null_ _null_ _null_ ));
 DESCR("statistics: information about currently active backends");
+DATA(insert OID = 3099 (  pg_stat_get_replication_activity	PGNSP PGUID 12 1 10 0 f f f f t s 0 0 2249 "" "{23,25}" "{o,o}" "{pid,sent_location}" _null_ pg_stat_get_replication_activity _null_ _null_ _null_ ));
+DESCR("statistics: information about currently active replication");
 DATA(insert OID = 2026 (  pg_backend_pid				PGNSP PGUID 12 1 0 0 f f f t f s 0 0 23 "" _null_ _null_ _null_ _null_ pg_backend_pid _null_ _null_ _null_ ));
 DESCR("statistics: current backend PID");
 DATA(insert OID = 1937 (  pg_stat_get_backend_pid		PGNSP PGUID 12 1 0 0 f f f t f s 1 0 23 "23" _null_ _null_ _null_ _null_ pg_stat_get_backend_pid _null_ _null_ _null_ ));
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to