From: Heikki Linnakangas Date: Fri, 23 Nov 2012 16:51:51 +0000 (+0200) Subject: pg_stat_replication.sync_state was displayed incorrectly at page boundary. X-Git-Tag: REL9_1_7~22 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=38b38fb12244c640230b1fd71d2c55ecc04844fa;p=postgresql pg_stat_replication.sync_state was displayed incorrectly at page boundary. XLogRecPtrIsInvalid() only checks the xrecoff field, which is correct when checking if a WAL record could legally begin at the given position, but WAL sending can legally be paused at a page boundary, in which case xrecoff is 0. Use XLByteEQ(..., InvalidXLogRecPtr) instead, which checks that both xlogid and xrecoff are 0. 9.3 doesn't have this problem because XLogRecPtr is now a single 64-bit integer, so XLogRecPtrIsInvalid() does the right thing. Apply to 9.2, and 9.1 where pg_stat_replication view was introduced. Kyotaro HORIGUCHI, reviewed by Fujii Masao. --- diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index 10af4e85c1..7fe9b09adf 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -375,6 +375,7 @@ SyncRepReleaseWaiters(void) int numprocs = 0; int priority = 0; int i; + XLogRecPtr InvalidXLogRecPtr = {0, 0}; /* * If this WALSender is serving a standby that is not on the list of @@ -384,7 +385,7 @@ SyncRepReleaseWaiters(void) */ if (MyWalSnd->sync_standby_priority == 0 || MyWalSnd->state < WALSNDSTATE_STREAMING || - XLogRecPtrIsInvalid(MyWalSnd->flush)) + XLByteEQ(MyWalSnd->flush, InvalidXLogRecPtr)) return; /* @@ -405,7 +406,7 @@ SyncRepReleaseWaiters(void) walsnd->sync_standby_priority > 0 && (priority == 0 || priority > walsnd->sync_standby_priority) && - !XLogRecPtrIsInvalid(walsnd->flush)) + !XLByteEQ(walsnd->flush, InvalidXLogRecPtr)) { priority = walsnd->sync_standby_priority; syncWalSnd = walsnd; diff --git a/src/backend/replication/walsender.c b/src/backend/replication/walsender.c index c5391676c4..7ccab20b13 100644 --- a/src/backend/replication/walsender.c +++ b/src/backend/replication/walsender.c @@ -1403,6 +1403,7 @@ pg_stat_get_wal_senders(PG_FUNCTION_ARGS) int priority = 0; int sync_standby = -1; int i; + XLogRecPtr InvalidXLogRecPtr = {0, 0}; /* check to see if caller supports us returning a tuplestore */ if (rsinfo == NULL || !IsA(rsinfo, ReturnSetInfo)) @@ -1448,14 +1449,14 @@ pg_stat_get_wal_senders(PG_FUNCTION_ARGS) * which always returns an invalid flush location, as an * asynchronous standby. */ - sync_priority[i] = XLogRecPtrIsInvalid(walsnd->flush) ? + sync_priority[i] = XLByteEQ(walsnd->flush, InvalidXLogRecPtr) ? 0 : walsnd->sync_standby_priority; if (walsnd->state == WALSNDSTATE_STREAMING && walsnd->sync_standby_priority > 0 && (priority == 0 || priority > walsnd->sync_standby_priority) && - !XLogRecPtrIsInvalid(walsnd->flush)) + !XLByteEQ(walsnd->flush, InvalidXLogRecPtr)) { priority = walsnd->sync_standby_priority; sync_standby = i;