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.
This commit is contained in:
parent
b5c077c368
commit
1b630751d0
@ -58,9 +58,12 @@ forgetIncompleteSplit(RelFileNode node, BlockNumber leftBlkno, BlockNumber updat
|
|||||||
{
|
{
|
||||||
ginIncompleteSplit *split = (ginIncompleteSplit *) lfirst(l);
|
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);
|
incomplete_splits = list_delete_ptr(incomplete_splits, split);
|
||||||
|
pfree(split);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -486,7 +489,7 @@ ginRedoUpdateMetapage(XLogRecPtr lsn, XLogRecord *record)
|
|||||||
|
|
||||||
metabuffer = XLogReadBuffer(data->node, GIN_METAPAGE_BLKNO, false);
|
metabuffer = XLogReadBuffer(data->node, GIN_METAPAGE_BLKNO, false);
|
||||||
if (!BufferIsValid(metabuffer))
|
if (!BufferIsValid(metabuffer))
|
||||||
elog(PANIC, "GIN metapage disappeared");
|
return; /* assume index was deleted, nothing to do */
|
||||||
metapage = BufferGetPage(metabuffer);
|
metapage = BufferGetPage(metabuffer);
|
||||||
|
|
||||||
if (!XLByteLE(lsn, PageGetLSN(metapage)))
|
if (!XLByteLE(lsn, PageGetLSN(metapage)))
|
||||||
@ -631,7 +634,7 @@ ginRedoDeleteListPages(XLogRecPtr lsn, XLogRecord *record)
|
|||||||
|
|
||||||
metabuffer = XLogReadBuffer(data->node, GIN_METAPAGE_BLKNO, false);
|
metabuffer = XLogReadBuffer(data->node, GIN_METAPAGE_BLKNO, false);
|
||||||
if (!BufferIsValid(metabuffer))
|
if (!BufferIsValid(metabuffer))
|
||||||
elog(PANIC, "GIN metapage disappeared");
|
return; /* assume index was deleted, nothing to do */
|
||||||
metapage = BufferGetPage(metabuffer);
|
metapage = BufferGetPage(metabuffer);
|
||||||
|
|
||||||
if (!XLByteLE(lsn, PageGetLSN(metapage)))
|
if (!XLByteLE(lsn, PageGetLSN(metapage)))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user