From: Ronan Dunklau <ronan.dunklau@aiven.io>
Subject: [PATCH] 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.cindex 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--
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] Detect invalid FSM when finding a block.
In-Reply-To: <no-message-id-25571@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