Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 4c8e20f

Browse files
committed
Track walsender state in shared memory and expose in pg_stat_replication
1 parent 47a5f3e commit 4c8e20f

File tree

7 files changed

+66
-6
lines changed

7 files changed

+66
-6
lines changed

doc/src/sgml/monitoring.sgml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -298,8 +298,8 @@ postgres: <replaceable>user</> <replaceable>database</> <replaceable>host</> <re
298298
<entry><structname>pg_stat_replication</><indexterm><primary>pg_stat_replication</primary></indexterm></entry>
299299
<entry>One row per WAL sender process, showing process <acronym>ID</>,
300300
user OID, user name, application name, client's address and port number,
301-
time at which the server process began execution, and transaction log
302-
location.
301+
time at which the server process began execution, current WAL sender
302+
state and transaction log location.
303303
</entry>
304304
</row>
305305

src/backend/catalog/system_views.sql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -501,6 +501,7 @@ CREATE VIEW pg_stat_replication AS
501501
S.client_addr,
502502
S.client_port,
503503
S.backend_start,
504+
W.state,
504505
W.sent_location
505506
FROM pg_stat_get_activity(NULL) AS S, pg_authid U,
506507
pg_stat_get_wal_senders() AS W

src/backend/replication/basebackup.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "libpq/pqformat.h"
2525
#include "nodes/pg_list.h"
2626
#include "replication/basebackup.h"
27+
#include "replication/walsender.h"
2728
#include "storage/fd.h"
2829
#include "storage/ipc.h"
2930
#include "utils/builtins.h"
@@ -115,6 +116,8 @@ SendBaseBackup(const char *options)
115116
ALLOCSET_DEFAULT_MAXSIZE);
116117
old_context = MemoryContextSwitchTo(backup_context);
117118

119+
WalSndSetState(WALSNDSTATE_BACKUP);
120+
118121
if (backup_label == NULL)
119122
ereport(FATAL,
120123
(errcode(ERRCODE_PROTOCOL_VIOLATION),

src/backend/replication/walsender.c

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,7 @@ WalSndHandshake(void)
179179
{
180180
int firstchar;
181181

182+
WalSndSetState(WALSNDSTATE_STARTUP);
182183
set_ps_display("idle", false);
183184

184185
/* Wait for a command to arrive */
@@ -482,6 +483,9 @@ WalSndLoop(void)
482483
if (!XLogSend(output_message, &caughtup))
483484
break;
484485
}
486+
487+
/* Update our state to indicate if we're behind or not */
488+
WalSndSetState(caughtup ? WALSNDSTATE_STREAMING : WALSNDSTATE_CATCHUP);
485489
}
486490

487491
/*
@@ -533,6 +537,7 @@ InitWalSnd(void)
533537
*/
534538
walsnd->pid = MyProcPid;
535539
MemSet(&walsnd->sentPtr, 0, sizeof(XLogRecPtr));
540+
walsnd->state = WALSNDSTATE_STARTUP;
536541
SpinLockRelease(&walsnd->mutex);
537542
/* don't need the lock anymore */
538543
OwnLatch((Latch *) &walsnd->latch);
@@ -960,14 +965,53 @@ WalSndWakeup(void)
960965
SetLatch(&WalSndCtl->walsnds[i].latch);
961966
}
962967

968+
/* Set state for current walsender (only called in walsender) */
969+
void
970+
WalSndSetState(WalSndState state)
971+
{
972+
/* use volatile pointer to prevent code rearrangement */
973+
volatile WalSnd *walsnd = MyWalSnd;
974+
975+
Assert(am_walsender);
976+
977+
if (walsnd->state == state)
978+
return;
979+
980+
SpinLockAcquire(&walsnd->mutex);
981+
walsnd->state = state;
982+
SpinLockRelease(&walsnd->mutex);
983+
}
984+
985+
/*
986+
* Return a string constant representing the state. This is used
987+
* in system views, and should *not* be translated.
988+
*/
989+
static const char *
990+
WalSndGetStateString(WalSndState state)
991+
{
992+
switch (state)
993+
{
994+
case WALSNDSTATE_STARTUP:
995+
return "STARTUP";
996+
case WALSNDSTATE_BACKUP:
997+
return "BACKUP";
998+
case WALSNDSTATE_CATCHUP:
999+
return "CATCHUP";
1000+
case WALSNDSTATE_STREAMING:
1001+
return "STREAMING";
1002+
}
1003+
return "UNKNOWN";
1004+
}
1005+
1006+
9631007
/*
9641008
* Returns activity of walsenders, including pids and xlog locations sent to
9651009
* standby servers.
9661010
*/
9671011
Datum
9681012
pg_stat_get_wal_senders(PG_FUNCTION_ARGS)
9691013
{
970-
#define PG_STAT_GET_WAL_SENDERS_COLS 2
1014+
#define PG_STAT_GET_WAL_SENDERS_COLS 3
9711015
ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
9721016
TupleDesc tupdesc;
9731017
Tuplestorestate *tupstore;
@@ -1021,7 +1065,8 @@ pg_stat_get_wal_senders(PG_FUNCTION_ARGS)
10211065

10221066
memset(nulls, 0, sizeof(nulls));
10231067
values[0] = Int32GetDatum(walsnd->pid);
1024-
values[1] = CStringGetTextDatum(sent_location);
1068+
values[1] = CStringGetTextDatum(WalSndGetStateString(walsnd->state));
1069+
values[2] = CStringGetTextDatum(sent_location);
10251070

10261071
tuplestore_putvalues(tupstore, tupdesc, values, nulls);
10271072
}

src/include/catalog/catversion.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,6 @@
5353
*/
5454

5555
/* yyyymmddN */
56-
#define CATALOG_VERSION_NO 201101081
56+
#define CATALOG_VERSION_NO 201101111
5757

5858
#endif

src/include/catalog/pg_proc.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3075,7 +3075,7 @@ DATA(insert OID = 1936 ( pg_stat_get_backend_idset PGNSP PGUID 12 1 100 0 f f
30753075
DESCR("statistics: currently active backend IDs");
30763076
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_ ));
30773077
DESCR("statistics: information about currently active backends");
3078-
DATA(insert OID = 3099 ( pg_stat_get_wal_senders PGNSP PGUID 12 1 10 0 f f f f t s 0 0 2249 "" "{23,25}" "{o,o}" "{procpid,sent_location}" _null_ pg_stat_get_wal_senders _null_ _null_ _null_ ));
3078+
DATA(insert OID = 3099 ( pg_stat_get_wal_senders PGNSP PGUID 12 1 10 0 f f f f t s 0 0 2249 "" "{23,25,25}" "{o,o,o}" "{procpid,state,sent_location}" _null_ pg_stat_get_wal_senders _null_ _null_ _null_ ));
30793079
DESCR("statistics: information about currently active replication");
30803080
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_ ));
30813081
DESCR("statistics: current backend PID");

src/include/replication/walsender.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,22 @@
1616
#include "storage/latch.h"
1717
#include "storage/spin.h"
1818

19+
20+
typedef enum WalSndState
21+
{
22+
WALSNDSTATE_STARTUP = 0,
23+
WALSNDSTATE_BACKUP,
24+
WALSNDSTATE_CATCHUP,
25+
WALSNDSTATE_STREAMING
26+
} WalSndState;
27+
1928
/*
2029
* Each walsender has a WalSnd struct in shared memory.
2130
*/
2231
typedef struct WalSnd
2332
{
2433
pid_t pid; /* this walsender's process id, or 0 */
34+
WalSndState state; /* this walsender's state */
2535
XLogRecPtr sentPtr; /* WAL has been sent up to this point */
2636

2737
slock_t mutex; /* locks shared variables shown above */
@@ -53,6 +63,7 @@ extern void WalSndSignals(void);
5363
extern Size WalSndShmemSize(void);
5464
extern void WalSndShmemInit(void);
5565
extern void WalSndWakeup(void);
66+
extern void WalSndSetState(WalSndState state);
5667

5768
extern Datum pg_stat_get_wal_senders(PG_FUNCTION_ARGS);
5869

0 commit comments

Comments
 (0)