pg.ddx.io  pgsql-bugs@postgresql.org mailing list archive  
help / color / mirror / Atom feed
[PATCH 2/2] Detect invalid FSM when finding a block.
1+ messages / 1 participants
[nested] [flat]

* [PATCH 2/2] Detect invalid FSM when finding a block.
@ 2024-03-06 08:12 Ronan Dunklau <ronan.dunklau@aiven.io>
  0 siblings, 0 replies; 1+ messages in thread

From: Ronan Dunklau @ 2024-03-06 08:12 UTC (permalink / raw)

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(-)

inline patch 1: src/backend/access/heap/hio.c (+19/-1 lines) download inline-1.patchdiff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c index ccc4c6966a2..1cf4c6354a1 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 */ @@ -583,6 +584,16 @@ RelationGetBufferForTuple(Relation relation, Size len, * target. */ targetBlock = GetPageWithFreeSpace(relation, targetFreeSpace); + nblocks = RelationGetNumberOfBlocks(relation); + /* + * 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
--nextPart3470556.QJadu78ljV-- ^ permalink raw reply [nested|flat] 1+ messages in thread


only message in thread

Thread overview: 1+ messages (download: mbox mbox.gz follow: Atom feed)
-- links below jump to the message on this page --
2024-03-06 08:12 [PATCH 2/2] Detect invalid FSM when finding a block. Ronan Dunklau <ronan.dunklau@aiven.io>

This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox