Don't advance checkPoint.nextXid near the end of a checkpoint sequence.
authorTom Lane <[email protected]>
Sun, 2 Dec 2012 20:19:57 +0000 (15:19 -0500)
committerTom Lane <[email protected]>
Sun, 2 Dec 2012 20:20:41 +0000 (15:20 -0500)
This reverts commit c11130690d6dca64267201a169cfb38c1adec5ef in favor of
actually fixing the problem: namely, that we should never have been
modifying the checkpoint record's nextXid at this point to begin with.
The nextXid should match the state as of the checkpoint's logical WAL
position (ie the redo point), not the state as of its physical position.
It's especially bogus to advance it in some wal_levels and not others.
In any case there is no need for the checkpoint record to carry the
same nextXid shown in the XLOG_RUNNING_XACTS record just emitted by
LogStandbySnapshot, as any replay operation will already have adopted
that value as current.

This fixes bug #7710 from Tarvi Pillessaar, and probably also explains bug
#6291 from Daniel Farina, in that if a checkpoint were in progress at the
instant of XID wraparound, the epoch bump would be lost as reported.
(And, of course, these days there's at least a 50-50 chance of a checkpoint
being in progress at any given instant.)

Diagnosed by me and independently by Andres Freund.  Back-patch to all
branches supporting hot standby.

src/backend/access/transam/xlog.c
src/backend/storage/ipc/standby.c
src/include/storage/standby.h

index f090baed4f18719e2f808ac7ca5b3a86a6aad175..9208bc21d462d51bd975b560a28e27f467fab39e 100644 (file)
@@ -7119,18 +7119,9 @@ CreateCheckPoint(int flags)
         *
         * If we are shutting down, or Startup process is completing crash
         * recovery we don't need to write running xact data.
-        *
-        * Update checkPoint.nextXid since we may have a later value. If we
-        * do update the value, and we have wrapped, increment epoch also.
         */
        if (!shutdown && XLogStandbyInfoActive())
-       {
-               TransactionId prevXid = checkPoint.nextXid;
-
-               LogStandbySnapshot(&checkPoint.nextXid);
-               if (checkPoint.nextXid < prevXid)
-                       checkPoint.nextXidEpoch++;
-       }
+               LogStandbySnapshot();
 
        START_CRIT_SECTION();
 
index 35548d1d1fbf3c9bb7e48d96adf9896e2de9cb4a..9f7cce4063995103c109ae9b039e7aa22acbb841 100644 (file)
@@ -848,7 +848,7 @@ standby_redo(XLogRecPtr lsn, XLogRecord *record)
  * from a time when they were possible.
  */
 void
-LogStandbySnapshot(TransactionId *nextXid)
+LogStandbySnapshot(void)
 {
        RunningTransactions running;
        xl_standby_lock *locks;
@@ -877,8 +877,6 @@ LogStandbySnapshot(TransactionId *nextXid)
        LogCurrentRunningXacts(running);
        /* GetRunningTransactionData() acquired XidGenLock, we must release it */
        LWLockRelease(XidGenLock);
-
-       *nextXid = running->nextXid;
 }
 
 /*
index f917b89f7e120ea8e4d7b10be91af8c78fc7df4f..34558a5a30eca00bb64ced9bd70f6f9318ed08d2 100644 (file)
@@ -113,6 +113,6 @@ typedef RunningTransactionsData *RunningTransactions;
 extern void LogAccessExclusiveLock(Oid dbOid, Oid relOid);
 extern void LogAccessExclusiveLockPrepare(void);
 
-extern void LogStandbySnapshot(TransactionId *nextXid);
+extern void LogStandbySnapshot(void);
 
 #endif   /* STANDBY_H */