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.
This commit is contained in:
Heikki Linnakangas 2012-11-23 18:51:51 +02:00
parent 806e6d1ddb
commit 38b38fb122
2 changed files with 6 additions and 4 deletions

View File

@ -375,6 +375,7 @@ SyncRepReleaseWaiters(void)
int numprocs = 0; int numprocs = 0;
int priority = 0; int priority = 0;
int i; int i;
XLogRecPtr InvalidXLogRecPtr = {0, 0};
/* /*
* If this WALSender is serving a standby that is not on the list of * 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 || if (MyWalSnd->sync_standby_priority == 0 ||
MyWalSnd->state < WALSNDSTATE_STREAMING || MyWalSnd->state < WALSNDSTATE_STREAMING ||
XLogRecPtrIsInvalid(MyWalSnd->flush)) XLByteEQ(MyWalSnd->flush, InvalidXLogRecPtr))
return; return;
/* /*
@ -405,7 +406,7 @@ SyncRepReleaseWaiters(void)
walsnd->sync_standby_priority > 0 && walsnd->sync_standby_priority > 0 &&
(priority == 0 || (priority == 0 ||
priority > walsnd->sync_standby_priority) && priority > walsnd->sync_standby_priority) &&
!XLogRecPtrIsInvalid(walsnd->flush)) !XLByteEQ(walsnd->flush, InvalidXLogRecPtr))
{ {
priority = walsnd->sync_standby_priority; priority = walsnd->sync_standby_priority;
syncWalSnd = walsnd; syncWalSnd = walsnd;

View File

@ -1403,6 +1403,7 @@ pg_stat_get_wal_senders(PG_FUNCTION_ARGS)
int priority = 0; int priority = 0;
int sync_standby = -1; int sync_standby = -1;
int i; int i;
XLogRecPtr InvalidXLogRecPtr = {0, 0};
/* check to see if caller supports us returning a tuplestore */ /* check to see if caller supports us returning a tuplestore */
if (rsinfo == NULL || !IsA(rsinfo, ReturnSetInfo)) 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 * which always returns an invalid flush location, as an
* asynchronous standby. * asynchronous standby.
*/ */
sync_priority[i] = XLogRecPtrIsInvalid(walsnd->flush) ? sync_priority[i] = XLByteEQ(walsnd->flush, InvalidXLogRecPtr) ?
0 : walsnd->sync_standby_priority; 0 : walsnd->sync_standby_priority;
if (walsnd->state == WALSNDSTATE_STREAMING && if (walsnd->state == WALSNDSTATE_STREAMING &&
walsnd->sync_standby_priority > 0 && walsnd->sync_standby_priority > 0 &&
(priority == 0 || (priority == 0 ||
priority > walsnd->sync_standby_priority) && priority > walsnd->sync_standby_priority) &&
!XLogRecPtrIsInvalid(walsnd->flush)) !XLByteEQ(walsnd->flush, InvalidXLogRecPtr))
{ {
priority = walsnd->sync_standby_priority; priority = walsnd->sync_standby_priority;
sync_standby = i; sync_standby = i;