pg.ddx.io  pgsql-bugs@postgresql.org mailing list archive  
help / color / mirror / Atom feed
From: Ronan Dunklau <ronan.dunklau@aiven.io>
Subject: [PATCH 2/2] Detect invalid FSM when finding a block.
Date: Wed, 6 Mar 2024 09:12:31 +0100

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

Message-ID: <no-message-id-25572@localhost>
Permalink:  ../no-message-id-25572@localhost/
Also on:    postgresql.org/message-id/no-message-id-25572@localhost

 ·  · 

reply

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Reply to all the recipients using the --to and --cc options:
  reply via email

  To: pgsql-bugs@postgresql.org
  Cc: ronan.dunklau@aiven.io
  Subject: Re: [PATCH 2/2] Detect invalid FSM when finding a block.
  In-Reply-To: <no-message-id-25572@localhost>

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

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