postgres.git / summary / log / commit / refs

commit    1b630751d0ffef4c856bfe382889d0d187eca404
Author:   Tom Lane <tgl@sss.pgh.pa.us>
Date:     Sun Feb 26 20:12:17 2012 +0000
First released in: 9.2.0, 8.4.12, 9.0.8, 9.1.4

    Fix some more bugs in GIN's WAL replay logic.
    
    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 | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/backend/access/gin/ginxlog.c b/src/backend/access/gin/ginxlog.c index 388589beac3..063d793565f 100644 --- a/src/backend/access/gin/ginxlog.c +++ b/src/backend/access/gin/ginxlog.c @@ -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))) [parent: b5c077c3685c]