1
0
mirror of https://github.com/postgres/postgres.git synced 2026-10-23 13:29:09 +03:00

Say in the FSM README why its hint writes still need full page images

The Recovery section said we would "operate correctly without the full page
images that MarkBufferDirtyHint() provides", offering them only as a way to
lose less slot knowledge to RBM_ZERO_ON_ERROR.  That is true of freespace.c,
which passes RBM_ZERO_ON_ERROR on every read, and false of the system around
it, which reads the same files and does verify checksums.  Reading it as a
licence to dirty FSM pages without a full page image is what led to
c06d1a4ba6, since reverted.

Say instead that RBM_ZERO_ON_ERROR is a property of this directory rather
than of the fork, and name the readers that do not share it:
RelationCopyStorage(), RelationCopyStorageUsingBuffer(), base backups and
pg_checksums.  Rather than presenting today's behavior as the only one
possible, note that the alternative is for all of that code to skip checksum
validation of the FSM.

Reported-by: Noah Misch <noah@leadboat.com>
Reviewed-by: Noah Misch <noah@leadboat.com>
Reviewed-by: Andrey Borodin <x4mmm@yandex-team.ru>
Discussion: https://postgr.es/m/20260901211837.f6.noahmisch%40microsoft.com
This commit is contained in:
Alexander Korotkov
2026-09-16 13:49:59 +03:00
parent d237a7a836
commit a4f18fd8f2

View File

@@ -189,9 +189,25 @@ to propagate the new free-space info into the upper pages of the FSM tree.
As a result when we write to the FSM we treat that as a hint and thus use
MarkBufferDirtyHint() rather than MarkBufferDirty(). Every read here uses
RBM_ZERO_ON_ERROR to bypass checksum mismatches and other verification
failures. We'd operate correctly without the full page images that
MarkBufferDirtyHint() provides, but they do decrease the chance of losing slot
knowledge to RBM_ZERO_ON_ERROR.
failures.
That RBM_ZERO_ON_ERROR is a property of this directory, not of the FSM fork
itself. The files themselves are ordinary relation files, and plenty of code
outside freespace.c reads them and does verify checksums:
RelationCopyStorage(), which ALTER TABLE ... SET TABLESPACE runs over every
fork; the read stream in RelationCopyStorageUsingBuffer(), used by
CREATE DATABASE ... STRATEGY = wal_log; and the checksum verification in base
backups and in pg_checksums. The alternative would be all such code skipping
checksum validation of *_fsm files, and that may be the right call someday.
Today they do verify, so what we write here has to be valid.
So the full page images MarkBufferDirtyHint() writes are not just an
optimization that reduces how often RBM_ZERO_ON_ERROR loses knowledge.
When checksums or wal_log_hints are enabled they are what keeps an FSM page
that reaches disk either checksum-valid or repairable by a later FPI. Do not
replace MarkBufferDirtyHint() with MarkBufferDirty() here on the grounds that
the FSM survives torn pages; it does, but the rest of the system is not
promised the same.
Relation extension is not WAL-logged. Hence, after WAL replay, an on-disk FSM
slot may indicate free space in PageIsNew() blocks that never reached disk.