@@ -179,6 +179,7 @@ WalSndHandshake(void)
179179{
180180int firstchar ;
181181
182+ WalSndSetState (WALSNDSTATE_STARTUP );
182183set_ps_display ("idle" , false);
183184
184185/* Wait for a command to arrive */
@@ -482,6 +483,9 @@ WalSndLoop(void)
482483if (!XLogSend (output_message ,& caughtup ))
483484break ;
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 */
534538walsnd -> pid = MyProcPid ;
535539MemSet (& walsnd -> sentPtr ,0 ,sizeof (XLogRecPtr ));
540+ walsnd -> state = WALSNDSTATE_STARTUP ;
536541SpinLockRelease (& walsnd -> mutex );
537542/* don't need the lock anymore */
538543OwnLatch ((Latch * )& walsnd -> latch );
@@ -960,14 +965,53 @@ WalSndWakeup(void)
960965SetLatch (& 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 */
9671011Datum
9681012pg_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
9711015ReturnSetInfo * rsinfo = (ReturnSetInfo * )fcinfo -> resultinfo ;
9721016TupleDesc tupdesc ;
9731017Tuplestorestate * tupstore ;
@@ -1021,7 +1065,8 @@ pg_stat_get_wal_senders(PG_FUNCTION_ARGS)
10211065
10221066memset (nulls ,0 ,sizeof (nulls ));
10231067values [0 ]= Int32GetDatum (walsnd -> pid );
1024- values [1 ]= CStringGetTextDatum (sent_location );
1068+ values [1 ]= CStringGetTextDatum (WalSndGetStateString (walsnd -> state ));
1069+ values [2 ]= CStringGetTextDatum (sent_location );
10251070
10261071tuplestore_putvalues (tupstore ,tupdesc ,values ,nulls );
10271072}