0001-Mark-modified-FSM-buffer-as-dirty-during-recovery.patch
text/x-patch
Filename: 0001-Mark-modified-FSM-buffer-as-dirty-during-recovery.patch
Type: text/x-patch
Part: 0
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: format-patch
Series: patch 0001
Subject: Mark modified FSM buffer as dirty during recovery.
| File | + | − |
|---|---|---|
| src/backend/storage/freespace/freespace.c | 1 | 1 |
From 3a51a4f3a920bed56910ae38f1c3f12059649c56 Mon Sep 17 00:00:00 2001 From: Alexey Makhmutov <a.makhmutov@postgrespro.ru> Date: Mon, 16 Mar 2026 13:32:45 +0300 Subject: [PATCH 1/2] Mark modified FSM buffer as dirty during recovery. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The XLogRecordPageWithFreeSpace function updates freespace map (FSM) data while replaying data-level WAL records during the recovery. If FSM block is updated, then it need to be marked as modified and currently this task is performed using MarkBufferDirtyHint call (as in all other cases for modifying of FSM data). However, in recovery context this function will actually do nothing if checksums are enabled. It’s assumed that page should not be dirtied during recovery while modifying hints to protect from torn pages as no new WAL data could be generated at this point to store FPI. Such logic seems to be not fully aligned with the FSM case, as its blocks could be just zeroed if checksum mismatch is detected. Currently changes to a FSM block could be lost if each change to the particular FSM block occur rarely enough to allow its eviction from the cache. To persist the change the modification need to be performed while FSM block is still kept in buffers and marked as dirty after receiving its FPI. If block was already cleaned, then the change won’t be persisted and stored FSM blocks may remain in an obsolete state. If large number of discrepancies between data in leaf FSM blocks and actual data blocks is accumulated on the replica server side, then this could cause significant delays for insert operations after switchover. Such insert operation may need to visit many data blocks marked as having enough space in FSM only to discover that this information is incorrect and FSM records need to be fixed. In a heavily trafficked insert-only table with many concurrent clients performing inserts this has been observed to cause several second stalls, causing visible application malfunction. Desire to avoid such cases was a reason behind the commit ab7dbd681, which introduced update of FSM data during the heap_xlog_visible invocation. However, as update to the FSM data on the standby side could be lost due to missing dirty flag, so there is still a possibility of hitting such situation. Note, that having a zeroed FSM page in such case (as result of checksum mismatch) is more preferable, as zero value will be interpreted as indication of full data blocks and inserter will be just routed to the next FSM block or to the end of the table. Given that FSM is ready to handle torn page writes and XLogRecordPageWithFreeSpace is called only during the recovery there seems to be no reason to use MarkBufferDirtyHint here instead of a regular MarkBufferDirty call. --- src/backend/storage/freespace/freespace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backend/storage/freespace/freespace.c b/src/backend/storage/freespace/freespace.c index b9a8f368a63..5c5d86bc106 100644 --- a/src/backend/storage/freespace/freespace.c +++ b/src/backend/storage/freespace/freespace.c @@ -232,7 +232,7 @@ XLogRecordPageWithFreeSpace(RelFileLocator rlocator, BlockNumber heapBlk, PageInit(page, BLCKSZ, 0); if (fsm_set_avail(page, slot, new_cat)) - MarkBufferDirtyHint(buf, false); + MarkBufferDirty(buf); UnlockReleaseBuffer(buf); } -- 2.53.0