Document WAL rules related to PD_ALL_VISIBLE in README.
Also improve comments. Discussion: https://postgr.es/m/a50005c1c537f89bb359057fd70e66bb83bce969.camel@j-davis.com Reviewed-by: Peter Geoghegan
This commit is contained in:
parent
d6a3dbe14f
commit
97c61f70d1
@ -8193,8 +8193,10 @@ log_heap_freeze(Relation reln, Buffer buffer, TransactionId cutoff_xid,
|
|||||||
* corresponding visibility map block. Both should have already been modified
|
* corresponding visibility map block. Both should have already been modified
|
||||||
* and dirtied.
|
* and dirtied.
|
||||||
*
|
*
|
||||||
* If checksums are enabled, we also generate a full-page image of
|
* If checksums or wal_log_hints are enabled, we may also generate a full-page
|
||||||
* heap_buffer, if necessary.
|
* image of heap_buffer. Otherwise, we optimize away the FPI (by specifying
|
||||||
|
* REGBUF_NO_IMAGE for the heap buffer), in which case the caller should *not*
|
||||||
|
* update the heap page's LSN.
|
||||||
*/
|
*/
|
||||||
XLogRecPtr
|
XLogRecPtr
|
||||||
log_heap_visible(RelFileLocator rlocator, Buffer heap_buffer, Buffer vm_buffer,
|
log_heap_visible(RelFileLocator rlocator, Buffer heap_buffer, Buffer vm_buffer,
|
||||||
|
@ -223,13 +223,13 @@ visibilitymap_pin_ok(BlockNumber heapBlk, Buffer vmbuf)
|
|||||||
* visibilitymap_set - set bit(s) on a previously pinned page
|
* visibilitymap_set - set bit(s) on a previously pinned page
|
||||||
*
|
*
|
||||||
* recptr is the LSN of the XLOG record we're replaying, if we're in recovery,
|
* recptr is the LSN of the XLOG record we're replaying, if we're in recovery,
|
||||||
* or InvalidXLogRecPtr in normal running. The page LSN is advanced to the
|
* or InvalidXLogRecPtr in normal running. The VM page LSN is advanced to the
|
||||||
* one provided; in normal running, we generate a new XLOG record and set the
|
* one provided; in normal running, we generate a new XLOG record and set the
|
||||||
* page LSN to that value. cutoff_xid is the largest xmin on the page being
|
* page LSN to that value (though the heap page's LSN may *not* be updated;
|
||||||
* marked all-visible; it is needed for Hot Standby, and can be
|
* see below). cutoff_xid is the largest xmin on the page being marked
|
||||||
* InvalidTransactionId if the page contains no tuples. It can also be set
|
* all-visible; it is needed for Hot Standby, and can be InvalidTransactionId
|
||||||
* to InvalidTransactionId when a page that is already all-visible is being
|
* if the page contains no tuples. It can also be set to InvalidTransactionId
|
||||||
* marked all-frozen.
|
* when a page that is already all-visible is being marked all-frozen.
|
||||||
*
|
*
|
||||||
* Caller is expected to set the heap page's PD_ALL_VISIBLE bit before calling
|
* Caller is expected to set the heap page's PD_ALL_VISIBLE bit before calling
|
||||||
* this function. Except in recovery, caller should also pass the heap
|
* this function. Except in recovery, caller should also pass the heap
|
||||||
@ -289,6 +289,11 @@ visibilitymap_set(Relation rel, BlockNumber heapBlk, Buffer heapBuf,
|
|||||||
/*
|
/*
|
||||||
* If data checksums are enabled (or wal_log_hints=on), we
|
* If data checksums are enabled (or wal_log_hints=on), we
|
||||||
* need to protect the heap page from being torn.
|
* need to protect the heap page from being torn.
|
||||||
|
*
|
||||||
|
* If not, then we must *not* update the heap page's LSN. In
|
||||||
|
* this case, the FPI for the heap page was omitted from the
|
||||||
|
* WAL record inserted above, so it would be incorrect to
|
||||||
|
* update the heap page's LSN.
|
||||||
*/
|
*/
|
||||||
if (XLogHintBitIsNeeded())
|
if (XLogHintBitIsNeeded())
|
||||||
{
|
{
|
||||||
|
@ -645,6 +645,23 @@ If you do decide to optimise away a WAL record, then any calls to
|
|||||||
MarkBufferDirty() must be replaced by MarkBufferDirtyHint(),
|
MarkBufferDirty() must be replaced by MarkBufferDirtyHint(),
|
||||||
otherwise you will expose the risk of partial page writes.
|
otherwise you will expose the risk of partial page writes.
|
||||||
|
|
||||||
|
The all-visible hint in a heap page (PD_ALL_VISIBLE) is a special
|
||||||
|
case, because it is treated like a durable change in some respects and
|
||||||
|
a hint in other respects. It must satisfy the invariant that, if a
|
||||||
|
heap page's associated visibilitymap (VM) bit is set, then
|
||||||
|
PD_ALL_VISIBLE is set on the heap page itself. Clearing of
|
||||||
|
PD_ALL_VISIBLE is always treated like a fully-durable change to
|
||||||
|
maintain this invariant. Additionally, if checksums or wal_log_hints
|
||||||
|
are enabled, setting PD_ALL_VISIBLE is also treated like a
|
||||||
|
fully-durable change to protect against torn pages.
|
||||||
|
|
||||||
|
But, if neither checksums nor wal_log_hints are enabled, torn pages
|
||||||
|
are of no consequence if the only change is to PD_ALL_VISIBLE; so no
|
||||||
|
full heap page image is taken, and the heap page's LSN is not
|
||||||
|
updated. NB: it would be incorrect to update the heap page's LSN when
|
||||||
|
applying this optimization, even though there is an associated WAL
|
||||||
|
record, because subsequent modifiers (e.g. an unrelated UPDATE) of the
|
||||||
|
page may falsely believe that a full page image is not required.
|
||||||
|
|
||||||
Write-Ahead Logging for Filesystem Actions
|
Write-Ahead Logging for Filesystem Actions
|
||||||
------------------------------------------
|
------------------------------------------
|
||||||
|
Loading…
x
Reference in New Issue
Block a user