postgres.git / summary / log / commit / refs

commit    f893af496100737b7fa1ef861ac8bd2705b4d5f1
Author:   Jeff Davis <jdavis@postgresql.org>
Date:     Thu Nov 10 22:46:30 2022 +0000

    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 fcb7e338982..fd30ce82ae1 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -8691,8 +8691,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. * @@ -8706,6 +8705,9 @@ heap_xlog_visible(XLogReaderState *record) PageSetAllVisible(page); + if (XLogHintBitIsNeeded()) + PageSetLSN(page, lsn); + MarkBufferDirty(buffer); } else if (action == BLK_RESTORED) [parent: 3383cf023484]