pg_stat_replication.sync_state was displayed incorrectly at page boundary.
authorHeikki Linnakangas <[email protected]>
Fri, 23 Nov 2012 16:51:51 +0000 (18:51 +0200)
committerHeikki Linnakangas <[email protected]>
Fri, 23 Nov 2012 17:14:54 +0000 (19:14 +0200)
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.

src/backend/replication/syncrep.c
src/backend/replication/walsender.c

index 088f7b67f91309cb9c37856c0fbe14ae3b486397..d3bec802656d2da78f359180153d690e79c5b913 100644 (file)
@@ -45,6 +45,7 @@
 
 #include <unistd.h>
 
+#include "access/transam.h"
 #include "access/xact.h"
 #include "miscadmin.h"
 #include "replication/syncrep.h"
@@ -382,7 +383,7 @@ SyncRepReleaseWaiters(void)
     */
    if (MyWalSnd->sync_standby_priority == 0 ||
        MyWalSnd->state < WALSNDSTATE_STREAMING ||
-       XLogRecPtrIsInvalid(MyWalSnd->flush))
+       XLByteEQ(MyWalSnd->flush, InvalidXLogRecPtr))
        return;
 
    /*
@@ -403,7 +404,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;
index 064ddd549531d660cb500bc7a620392b42067ade..6c274497072f0de8cc3874766d2047600c054faa 100644 (file)
@@ -1559,14 +1559,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;