In SPGiST replay, do conflict resolution before modifying the page.
In yesterday's commit 962e0cc71e
, I added the
ResolveRecoveryConflictWithSnapshot call in the wrong place. I correctly
put it before spgRedoVacuumRedirect itself would modify the index page ---
but not before RestoreBkpBlocks, so replay of a record with a full-page
image would modify the page before kicking off any conflicting HS
transactions. Oops.
This commit is contained in:
parent
9fb5952cdf
commit
c1793f2e0c
|
@ -889,15 +889,6 @@ spgRedoVacuumRedirect(XLogRecPtr lsn, XLogRecord *record)
|
||||||
ptr += sizeof(spgxlogVacuumRedirect);
|
ptr += sizeof(spgxlogVacuumRedirect);
|
||||||
itemToPlaceholder = (OffsetNumber *) ptr;
|
itemToPlaceholder = (OffsetNumber *) ptr;
|
||||||
|
|
||||||
/*
|
|
||||||
* If any redirection tuples are being removed, make sure there are no
|
|
||||||
* live Hot Standby transactions that might need to see them. This code
|
|
||||||
* behaves similarly to btree's XLOG_BTREE_REUSE_PAGE case.
|
|
||||||
*/
|
|
||||||
if (InHotStandby && TransactionIdIsValid(xldata->newestRedirectXid))
|
|
||||||
ResolveRecoveryConflictWithSnapshot(xldata->newestRedirectXid,
|
|
||||||
xldata->node);
|
|
||||||
|
|
||||||
if (!(record->xl_info & XLR_BKP_BLOCK_1))
|
if (!(record->xl_info & XLR_BKP_BLOCK_1))
|
||||||
{
|
{
|
||||||
buffer = XLogReadBuffer(xldata->node, xldata->blkno, false);
|
buffer = XLogReadBuffer(xldata->node, xldata->blkno, false);
|
||||||
|
@ -964,10 +955,33 @@ spg_redo(XLogRecPtr lsn, XLogRecord *record)
|
||||||
MemoryContext oldCxt;
|
MemoryContext oldCxt;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* SP-GiST indexes do not require any conflict processing. NB: If we ever
|
* If we have any conflict processing to do, it must happen before we
|
||||||
* implement a similar optimization as we have in b-tree, and remove
|
* update the page.
|
||||||
* killed tuples outside VACUUM, we'll need to handle that here.
|
|
||||||
*/
|
*/
|
||||||
|
if (InHotStandby)
|
||||||
|
{
|
||||||
|
switch (info)
|
||||||
|
{
|
||||||
|
case XLOG_SPGIST_VACUUM_REDIRECT:
|
||||||
|
{
|
||||||
|
spgxlogVacuumRedirect *xldata =
|
||||||
|
(spgxlogVacuumRedirect *) XLogRecGetData(record);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If any redirection tuples are being removed, make sure
|
||||||
|
* there are no live Hot Standby transactions that might
|
||||||
|
* need to see them.
|
||||||
|
*/
|
||||||
|
if (TransactionIdIsValid(xldata->newestRedirectXid))
|
||||||
|
ResolveRecoveryConflictWithSnapshot(xldata->newestRedirectXid,
|
||||||
|
xldata->node);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
RestoreBkpBlocks(lsn, record, false);
|
RestoreBkpBlocks(lsn, record, false);
|
||||||
|
|
||||||
oldCxt = MemoryContextSwitchTo(opCtx);
|
oldCxt = MemoryContextSwitchTo(opCtx);
|
||||||
|
|
Loading…
Reference in New Issue