@@ -124,6 +124,7 @@ static void XLogWalRcvWrite(char *buf, Size nbytes, XLogRecPtr recptr);
124
124
static void XLogWalRcvFlush (bool dying );
125
125
static void XLogWalRcvSendReply (void );
126
126
static void XLogWalRcvSendHSFeedback (void );
127
+ static void ProcessWalSndrMessage (XLogRecPtr walEnd , TimestampTz sendTime );
127
128
128
129
/* Signal handlers */
129
130
static void WalRcvSigHupHandler (SIGNAL_ARGS );
@@ -218,6 +219,10 @@ WalReceiverMain(void)
218
219
/* Fetch information required to start streaming */
219
220
strlcpy (conninfo , (char * ) walrcv -> conninfo , MAXCONNINFO );
220
221
startpoint = walrcv -> receiveStart ;
222
+
223
+ /* Initialise to a sanish value */
224
+ walrcv -> lastMsgSendTime = walrcv -> lastMsgReceiptTime = GetCurrentTimestamp ();
225
+
221
226
SpinLockRelease (& walrcv -> mutex );
222
227
223
228
/* Arrange to clean up at walreceiver exit */
@@ -433,12 +438,28 @@ XLogWalRcvProcessMsg(unsigned char type, char *buf, Size len)
433
438
errmsg_internal ("invalid WAL message received from primary" )));
434
439
/* memcpy is required here for alignment reasons */
435
440
memcpy (& msghdr , buf , sizeof (WalDataMessageHeader ));
441
+
442
+ ProcessWalSndrMessage (msghdr .walEnd , msghdr .sendTime );
443
+
436
444
buf += sizeof (WalDataMessageHeader );
437
445
len -= sizeof (WalDataMessageHeader );
438
-
439
446
XLogWalRcvWrite (buf , len , msghdr .dataStart );
440
447
break ;
441
448
}
449
+ case 'k' : /* Keepalive */
450
+ {
451
+ PrimaryKeepaliveMessage keepalive ;
452
+
453
+ if (len != sizeof (PrimaryKeepaliveMessage ))
454
+ ereport (ERROR ,
455
+ (errcode (ERRCODE_PROTOCOL_VIOLATION ),
456
+ errmsg_internal ("invalid keepalive message received from primary" )));
457
+ /* memcpy is required here for alignment reasons */
458
+ memcpy (& keepalive , buf , sizeof (PrimaryKeepaliveMessage ));
459
+
460
+ ProcessWalSndrMessage (keepalive .walEnd , keepalive .sendTime );
461
+ break ;
462
+ }
442
463
default :
443
464
ereport (ERROR ,
444
465
(errcode (ERRCODE_PROTOCOL_VIOLATION ),
@@ -711,3 +732,27 @@ XLogWalRcvSendHSFeedback(void)
711
732
memcpy (& buf [1 ], & feedback_message , sizeof (StandbyHSFeedbackMessage ));
712
733
walrcv_send (buf , sizeof (StandbyHSFeedbackMessage ) + 1 );
713
734
}
735
+
736
+ /*
737
+ * Keep track of important messages from primary.
738
+ */
739
+ static void
740
+ ProcessWalSndrMessage (XLogRecPtr walEnd , TimestampTz sendTime )
741
+ {
742
+ /* use volatile pointer to prevent code rearrangement */
743
+ volatile WalRcvData * walrcv = WalRcv ;
744
+
745
+ TimestampTz lastMsgReceiptTime = GetCurrentTimestamp ();
746
+
747
+ /* Update shared-memory status */
748
+ SpinLockAcquire (& walrcv -> mutex );
749
+ walrcv -> lastMsgSendTime = sendTime ;
750
+ walrcv -> lastMsgReceiptTime = lastMsgReceiptTime ;
751
+ SpinLockRelease (& walrcv -> mutex );
752
+
753
+ elog (DEBUG2 , "sendtime %s receipttime %s replication apply delay %d transfer latency %d" ,
754
+ timestamptz_to_str (sendTime ),
755
+ timestamptz_to_str (lastMsgReceiptTime ),
756
+ GetReplicationApplyDelay (),
757
+ GetReplicationTransferLatency ());
758
+ }
0 commit comments