From: Ronan Dunklau Date: Wed, 6 Mar 2024 09:12:31 +0100 Subject: [PATCH] Detect invalid FSM when finding a block. Whenever the FSM points to a block past the end of the relation, detect it and fallback to the relation extension mechanism. This may arise when a FPI for the FSM has been triggered, and we end up WAL-logging a page of the FSM pointing to newly extended blocks in the relation which have never been WAL-logged. --- src/backend/access/heap/hio.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c index ccc4c6966a2..623406d57e7 100644 --- a/src/backend/access/heap/hio.c +++ b/src/backend/access/heap/hio.c @@ -517,6 +517,7 @@ RelationGetBufferForTuple(Relation relation, Size len, otherBlock; bool unlockedTargetBuffer; bool recheckVmPins; + BlockNumber nblocks = InvalidBlockNumber; len = MAXALIGN(len); /* be conservative */ @@ -582,7 +583,17 @@ RelationGetBufferForTuple(Relation relation, Size len, * We have no cached target page, so ask the FSM for an initial * target. */ + nblocks = RelationGetNumberOfBlocks(relation); targetBlock = GetPageWithFreeSpace(relation, targetFreeSpace); + /* + * Since relation extension are not wal logged, the fsm could end up + * pointing to an unlogged empty segment. + * Detect it, and fall back through trying the last page + */ + if (unlikely(targetBlock >= nblocks)) + { + targetBlock = InvalidBlockNumber; + } } /* @@ -592,7 +603,8 @@ RelationGetBufferForTuple(Relation relation, Size len, */ if (targetBlock == InvalidBlockNumber) { - BlockNumber nblocks = RelationGetNumberOfBlocks(relation); + if (nblocks == InvalidBlockNumber) + nblocks = RelationGetNumberOfBlocks(relation); if (nblocks > 0) targetBlock = nblocks - 1; @@ -761,6 +773,12 @@ loop: targetBlock, pageFreeSpace, targetFreeSpace); + /* As above, if the FSM gives us a page past the end of the relation, + * give up and fallback to extending the relation */ + if (nblocks == InvalidBlockNumber) + nblocks = RelationGetNumberOfBlocks(relation); + if (targetBlock >= nblocks) + targetBlock = InvalidBlockNumber; } } -- 2.44.0 --nextPart22206681.EfDdHjke4D--