mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-10-02 18:56:53 +02:00
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);
|
||||||
@ -1072,7 +1086,7 @@ spg_desc(StringInfo buf, uint8 xl_info, char *rec)
|
|||||||
out_target(buf, ((spgxlogVacuumRedirect *) rec)->node);
|
out_target(buf, ((spgxlogVacuumRedirect *) rec)->node);
|
||||||
appendStringInfo(buf, "vacuum redirect tuples on page %u, newest XID %u",
|
appendStringInfo(buf, "vacuum redirect tuples on page %u, newest XID %u",
|
||||||
((spgxlogVacuumRedirect *) rec)->blkno,
|
((spgxlogVacuumRedirect *) rec)->blkno,
|
||||||
((spgxlogVacuumRedirect *) rec)->newestRedirectXid);
|
((spgxlogVacuumRedirect *) rec)->newestRedirectXid);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
appendStringInfo(buf, "unknown spgist op code %u", info);
|
appendStringInfo(buf, "unknown spgist op code %u", info);
|
||||||
|
Loading…
Reference in New Issue
Block a user