postgres.git / summary / log / commit / refs
commit 57b100fe0fb1d0d5803789d3113b89fa18a34fad
Author: Tom Lane <tgl@sss.pgh.pa.us>
Date: Sun Feb 26 20:12:23 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 66d881e96dd..de848ecdf07 100644
--- a/src/backend/access/gin/ginxlog.c
+++ b/src/backend/access/gin/ginxlog.c
@@ -59,9 +59,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;
}
}
@@ -487,7 +490,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)))
@@ -632,7 +635,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: 64c47e454291]