]> granicus.if.org Git - postgresql/commitdiff
Reduce impact of btree page reuse on Hot Standby by fixing off-by-1 error.
authorSimon Riggs <simon@2ndQuadrant.com>
Mon, 27 Jun 2011 21:15:07 +0000 (22:15 +0100)
committerSimon Riggs <simon@2ndQuadrant.com>
Mon, 27 Jun 2011 21:15:07 +0000 (22:15 +0100)
WAL records of type XLOG_BTREE_REUSE_PAGE were generated using a
latestRemovedXid one higher than actually needed because xid used was
page opaque->btpo.xact rather than an actually removed xid.
Noticed on an otherwise quiet system by Noah Misch.

Noah Misch and Simon Riggs

src/backend/access/nbtree/nbtpage.c

index 65354e6d28fa3accfcf989d79106984af87edce5..4b1a2e912b640458e2c4057fbd16d933cd1b3419 100644 (file)
@@ -560,9 +560,19 @@ _bt_getbuf(Relation rel, BlockNumber blkno, int access)
                                         */
                                        if (XLogStandbyInfoActive())
                                        {
+                                               TransactionId latestRemovedXid;
+
                                                BTPageOpaque opaque = (BTPageOpaque) PageGetSpecialPointer(page);
 
-                                               _bt_log_reuse_page(rel, blkno, opaque->btpo.xact);
+                                               /*
+                                                * opaque->btpo.xact is the threshold value not the
+                                                * value to measure conflicts against. We must retreat
+                                                * by one from it to get the correct conflict xid.
+                                                */
+                                               latestRemovedXid = opaque->btpo.xact;
+                                               TransactionIdRetreat(latestRemovedXid);
+
+                                               _bt_log_reuse_page(rel, blkno, latestRemovedXid);
                                        }
 
                                        /* Okay to use page.  Re-initialize and return it */