Correct StartupSUBTRANS for page wraparound
authorSimon Riggs <simon@2ndQuadrant.com>
Fri, 19 Feb 2016 08:32:28 +0000 (08:32 +0000)
committerSimon Riggs <simon@2ndQuadrant.com>
Fri, 19 Feb 2016 08:32:28 +0000 (08:32 +0000)
StartupSUBTRANS() incorrectly handled cases near the max pageid in the subtrans
data structure, which in some cases could lead to errors in startup for Hot
Standby.
This patch wraps the pageids correctly, avoiding any such errors.
Identified by exhaustive crash testing by Jeff Janes.

Jeff Janes

src/backend/access/transam/subtrans.c

index 659c95bce1edb57101d0f8c46fb4d348f7177674..e7d007ac2ccd7d69a7e2560d1b405e0fd97a7499 100644 (file)
@@ -44,7 +44,8 @@
  * 0xFFFFFFFF/SUBTRANS_XACTS_PER_PAGE, and segment numbering at
  * 0xFFFFFFFF/SUBTRANS_XACTS_PER_PAGE/SLRU_PAGES_PER_SEGMENT.  We need take no
  * explicit notice of that fact in this module, except when comparing segment
- * and page numbers in TruncateSUBTRANS (see SubTransPagePrecedes).
+ * and page numbers in TruncateSUBTRANS (see SubTransPagePrecedes) and zeroing
+ * them in StartupSUBTRANS.
  */
 
 /* We need four bytes per xact */
@@ -253,6 +254,9 @@ StartupSUBTRANS(TransactionId oldestActiveXID)
    {
        (void) ZeroSUBTRANSPage(startPage);
        startPage++;
+       /* must account for wraparound */
+       if (startPage > TransactionIdToPage(MaxTransactionId))
+           startPage=0;
    }
    (void) ZeroSUBTRANSPage(startPage);