postgres.git / summary / log / commit / refs
commit d6a3dbe14f98d867b2fc3faeb99d2d3c2a48ca67
Author: Jeff Davis <jdavis@postgresql.org>
Date: Thu Nov 10 22:46:30 2022 +0000
First released in: 16.0, 11.19, 12.14, 13.10, 14.7, 15.2
Fix theoretical torn page hazard.
The original report was concerned with a possible inconsistency
between the heap and the visibility map, which I was unable to
confirm. The concern has been retracted.
However, there did seem to be a torn page hazard when using
checksums. By not setting the heap page LSN during redo, the
protections of minRecoveryPoint were bypassed. Fixed, along with a
misleading comment.
It may have been impossible to hit this problem in practice, because
it would require a page tear between the checksum and the flags, so I
am marking this as a theoretical risk. But, as discussed, it did
violate expectations about the page LSN, so it may have other
consequences.
Backpatch to all supported versions.
Reported-by: Konstantin Knizhnik
Reviewed-by: Konstantin Knizhnik
Discussion: https://postgr.es/m/fed17dac-8cb8-4f5b-d462-1bb4908c029e@garret.ru
Backpatch-through: 11
src/backend/access/heap/heapam.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c
index 560f1c81a2c..5c8cdfb9b20 100644
--- a/src/backend/access/heap/heapam.c
+++ b/src/backend/access/heap/heapam.c
@@ -8823,8 +8823,7 @@ heap_xlog_visible(XLogReaderState *record)
/*
* We don't bump the LSN of the heap page when setting the visibility
* map bit (unless checksums or wal_hint_bits is enabled, in which
- * case we must), because that would generate an unworkable volume of
- * full-page writes. This exposes us to torn page hazards, but since
+ * case we must). This exposes us to torn page hazards, but since
* we're not inspecting the existing page contents in any way, we
* don't care.
*/
@@ -8832,6 +8831,9 @@ heap_xlog_visible(XLogReaderState *record)
PageSetAllVisible(page);
+ if (XLogHintBitIsNeeded())
+ PageSetLSN(page, lsn);
+
MarkBufferDirty(buffer);
}
else if (action == BLK_RESTORED)
[parent: 3eb8eeccbee3]