diff options
author | Tom Lane | 2012-02-26 20:12:34 +0000 |
---|---|---|
committer | Tom Lane | 2012-02-26 20:12:34 +0000 |
commit | 5ce0a842a6e93ecb453490dc1b6a578b40da1630 (patch) | |
tree | efe0b3fa7b9d9613f86c774f5f710e324468bad9 | |
parent | 0209a10bf8e53809529bbe916b6ff2185fd61b96 (diff) |
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.
-rw-r--r-- | src/backend/access/gin/ginxlog.c | 9 |
1 files changed, 6 insertions, 3 deletions
diff --git a/src/backend/access/gin/ginxlog.c b/src/backend/access/gin/ginxlog.c index 864cab28fd0..6fc55311576 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; } } @@ -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))) |