+ * Return a string constant representing the state. This is used
+ * in system functions and views, and should *not* be translated.
+WalRcvGetStateString(WalRcvState state)
+ case WALRCV_RESTARTING:
+ * Returns activity of WAL receiver, including pid, state and xlog locations
+ * received from the WAL sender of another server.
+pg_stat_get_wal_receiver(PG_FUNCTION_ARGS)
+#define PG_STAT_GET_WAL_RECEIVER_COLS 11
+ Datum values[PG_STAT_GET_WAL_RECEIVER_COLS];
+ bool nulls[PG_STAT_GET_WAL_RECEIVER_COLS];
+ WalRcvData *walrcv = WalRcv;
+ XLogRecPtr receive_start_lsn;
+ TimeLineID receive_start_tli;
+ XLogRecPtr received_lsn;
+ TimeLineID received_tli;
+ TimestampTz last_send_time;
+ TimestampTz last_receipt_time;
+ XLogRecPtr latest_end_lsn;
+ TimestampTz latest_end_time;
+ /* No WAL receiver, just return a tuple with NULL values */
+ /* Initialise values and NULL flags arrays */
+ MemSet(values, 0, sizeof(values));
+ MemSet(nulls, 0, sizeof(nulls));
+ /* Initialise attributes information in the tuple descriptor */
+ tupdesc = CreateTemplateTupleDesc(PG_STAT_GET_WAL_RECEIVER_COLS, false);
+ TupleDescInitEntry(tupdesc, (AttrNumber) 1, "pid",
+ TupleDescInitEntry(tupdesc, (AttrNumber) 2, "status",
+ TupleDescInitEntry(tupdesc, (AttrNumber) 3, "receive_start_lsn",
+ TupleDescInitEntry(tupdesc, (AttrNumber) 4, "receive_start_tli",
+ TupleDescInitEntry(tupdesc, (AttrNumber) 5, "received_lsn",
+ TupleDescInitEntry(tupdesc, (AttrNumber) 6, "received_tli",
+ TupleDescInitEntry(tupdesc, (AttrNumber) 7, "last_msg_send_time",
+ TIMESTAMPTZOID, -1, 0);
+ TupleDescInitEntry(tupdesc, (AttrNumber) 8, "last_msg_receipt_time",
+ TIMESTAMPTZOID, -1, 0);
+ TupleDescInitEntry(tupdesc, (AttrNumber) 9, "latest_end_lsn",
+ TupleDescInitEntry(tupdesc, (AttrNumber) 10, "latest_end_time",
+ TIMESTAMPTZOID, -1, 0);
+ TupleDescInitEntry(tupdesc, (AttrNumber) 11, "slot_name",
+ BlessTupleDesc(tupdesc);
+ /* Take a lock to ensure value consistency */
+ SpinLockAcquire(&walrcv->mutex);
+ state = walrcv->walRcvState;
+ receive_start_lsn = walrcv->receiveStart;
+ receive_start_tli = walrcv->receiveStartTLI;
+ received_lsn = walrcv->receivedUpto;
+ received_tli = walrcv->receivedTLI;
+ last_send_time = walrcv->lastMsgSendTime;
+ last_receipt_time = walrcv->lastMsgReceiptTime;
+ latest_end_lsn = walrcv->latestWalEnd;
+ latest_end_time = walrcv->latestWalEndTime;
+ slotname = pstrdup(walrcv->slotname);
+ SpinLockRelease(&walrcv->mutex);
+ values[0] = Int32GetDatum(walrcv->pid);
+ * Only superusers can see details. Other users only get the pid
+ * value to know whether it is a WAL receiver, but no details.
+ MemSet(&nulls[1], true, PG_STAT_GET_WAL_RECEIVER_COLS - 1);
+ values[1] = CStringGetTextDatum(WalRcvGetStateString(state));
+ if (XLogRecPtrIsInvalid(receive_start_lsn))
+ values[2] = LSNGetDatum(receive_start_lsn);
+ values[3] = Int32GetDatum(receive_start_tli);
+ if (XLogRecPtrIsInvalid(received_lsn))
+ values[4] = LSNGetDatum(received_lsn);
+ values[5] = Int32GetDatum(received_tli);
+ if (last_send_time == 0)
+ values[6] = TimestampTzGetDatum(last_send_time);
+ if (last_receipt_time == 0)
+ values[7] = TimestampTzGetDatum(last_receipt_time);
+ if (XLogRecPtrIsInvalid(latest_end_lsn))
+ values[8] = LSNGetDatum(latest_end_lsn);
+ if (latest_end_time == 0)
+ values[9] = TimestampTzGetDatum(latest_end_time);
+ values[10] = CStringGetTextDatum(slotname);
+ /* Returns the record as Datum */
+ PG_RETURN_DATUM(HeapTupleGetDatum(
+ heap_form_tuple(tupdesc, values, nulls)));