Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Fix some more bugs in GIN's WAL replay logic.
authorTom Lane <tgl@sss.pgh.pa.us>
Sun, 26 Feb 2012 20:12:17 +0000 (15:12 -0500)
committerTom Lane <tgl@sss.pgh.pa.us>
Sun, 26 Feb 2012 20:12:17 +0000 (15:12 -0500)
In commit 4016bdef8aded77b4903c457050622a5a1815c16 I fixed a bunch of
ginxlog.c bugs having to do with not handling XLogReadBuffer failures
correctly.  However, in ginRedoUpdateMetapage and ginRedoDeleteListPages,
I unaccountably thought that failure to read the metapage would be
impossible and just put in an elog(PANIC) call.  This is of course wrong:
failure is exactly what will happen if the index got dropped (or rebuilt)
between creation of the WAL record and the crash we're trying to recover
from.  I believe this explains Nicholas Wilson's recent report of these
errors getting reached.

Also, fix memory leak in forgetIncompleteSplit.  This wasn't of much
concern when the code was written, but in a long-running standby server
page split records could be expected to accumulate indefinitely.

Back-patch to 8.4 --- before that, GIN didn't have a metapage.

src/backend/access/gin/ginxlog.c

index 388589beac33bb8d158b2ba43921e3c7ec1e338b..063d793565ff9d29f179929c325b5d4096d4bbe5 100644 (file)
@@ -58,9 +58,12 @@ forgetIncompleteSplit(RelFileNode node, BlockNumber leftBlkno, BlockNumber updat
    {
        ginIncompleteSplit *split = (ginIncompleteSplit *) lfirst(l);
 
-       if (RelFileNodeEquals(node, split->node) && leftBlkno == split->leftBlkno && updateBlkno == split->rightBlkno)
+       if (RelFileNodeEquals(node, split->node) &&
+           leftBlkno == split->leftBlkno &&
+           updateBlkno == split->rightBlkno)
        {
            incomplete_splits = list_delete_ptr(incomplete_splits, split);
+           pfree(split);
            break;
        }
    }
@@ -486,7 +489,7 @@ ginRedoUpdateMetapage(XLogRecPtr lsn, XLogRecord *record)
 
    metabuffer = XLogReadBuffer(data->node, GIN_METAPAGE_BLKNO, false);
    if (!BufferIsValid(metabuffer))
-       elog(PANIC, "GIN metapage disappeared");
+       return;                 /* assume index was deleted, nothing to do */
    metapage = BufferGetPage(metabuffer);
 
    if (!XLByteLE(lsn, PageGetLSN(metapage)))
@@ -631,7 +634,7 @@ ginRedoDeleteListPages(XLogRecPtr lsn, XLogRecord *record)
 
    metabuffer = XLogReadBuffer(data->node, GIN_METAPAGE_BLKNO, false);
    if (!BufferIsValid(metabuffer))
-       elog(PANIC, "GIN metapage disappeared");
+       return;                 /* assume index was deleted, nothing to do */
    metapage = BufferGetPage(metabuffer);
 
    if (!XLByteLE(lsn, PageGetLSN(metapage)))