Awhile back I added some code to StartupCLOG() to forcibly zero out
authorTom Lane <[email protected]>
Wed, 22 Dec 2004 18:45:49 +0000 (18:45 +0000)
committerTom Lane <[email protected]>
Wed, 22 Dec 2004 18:45:49 +0000 (18:45 +0000)
the remainder of the current clog page during system startup.  While
this was a good idea, it turns out the code fails if nextXid is
exactly at a page boundary, because we won't have created the "current"
clog page yet in that case.  Since the page will be correctly zeroed
when we execute the first transaction on it, the solution is just to
do nothing when exactly at a page boundary.  Per trouble report from
Dave Hartwig.

src/backend/access/transam/clog.c

index b8d8abd7b4c909a4fbaf420fc81d85a58f700e5b..6d114524f6c747c9603e094a71f2157d7369e97a 100644 (file)
@@ -212,10 +212,6 @@ StartupCLOG(void)
 {
        TransactionId xid = ShmemVariableCache->nextXid;
        int                     pageno = TransactionIdToPage(xid);
-       int                     byteno = TransactionIdToByte(xid);
-       int                     bshift = TransactionIdToBIndex(xid) * CLOG_BITS_PER_XACT;
-       int                     slotno;
-       char       *byteptr;
 
        LWLockAcquire(CLogControlLock, LW_EXCLUSIVE);
 
@@ -232,17 +228,27 @@ StartupCLOG(void)
         * marked by the previous database lifecycle (since subtransaction
         * commit writes clog but makes no WAL entry).  Let's just be safe.
         * (We need not worry about pages beyond the current one, since those
-        * will be zeroed when first used.)
+        * will be zeroed when first used.  For the same reason, there is no
+        * need to do anything when nextXid is exactly at a page boundary; and
+        * it's likely that the "current" page doesn't exist yet in that case.)
         */
-       slotno = SimpleLruReadPage(ClogCtl, pageno, xid);
-       byteptr = ClogCtl->shared->page_buffer[slotno] + byteno;
+       if (TransactionIdToPgIndex(xid) != 0)
+       {
+               int                     byteno = TransactionIdToByte(xid);
+               int                     bshift = TransactionIdToBIndex(xid) * CLOG_BITS_PER_XACT;
+               int                     slotno;
+               char       *byteptr;
 
-       /* Zero so-far-unused positions in the current byte */
-       *byteptr &= (1 << bshift) - 1;
-       /* Zero the rest of the page */
-       MemSet(byteptr + 1, 0, BLCKSZ - byteno - 1);
+               slotno = SimpleLruReadPage(ClogCtl, pageno, xid);
+               byteptr = ClogCtl->shared->page_buffer[slotno] + byteno;
 
-       ClogCtl->shared->page_status[slotno] = SLRU_PAGE_DIRTY;
+               /* Zero so-far-unused positions in the current byte */
+               *byteptr &= (1 << bshift) - 1;
+               /* Zero the rest of the page */
+               MemSet(byteptr + 1, 0, BLCKSZ - byteno - 1);
+
+               ClogCtl->shared->page_status[slotno] = SLRU_PAGE_DIRTY;
+       }
 
        LWLockRelease(CLogControlLock);
 }