🌐 AI搜索 & 代理 主页
Skip to content

Commit 8180136

Browse files
committed
Comment on need to MarkBufferDirty() if omitting DELAY_CHKPT_START.
Blocking checkpoint phase 2 requires MarkBufferDirty() and BUFFER_LOCK_EXCLUSIVE; neither suffices by itself. transam/README documents this, citing SyncOneBuffer(). Update the DELAY_CHKPT_START documentation to say this. Expand the heap_inplace_update_and_unlock() comment that cites XLogSaveBufferForHint() as precedent, since heap_inplace_update_and_unlock() could have opted not to use DELAY_CHKPT_START. Commit 8e7e672 added DELAY_CHKPT_START to heap_inplace_update_and_unlock(). Since commit bc6bad8 reverted it in non-master branches, no back-patch. Discussion: https://postgr.es/m/20250406180054.26.nmisch@google.com
1 parent 714bd9e commit 8180136

File tree

2 files changed

+15
-7
lines changed

2 files changed

+15
-7
lines changed

src/backend/access/heap/heapam.c

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6507,9 +6507,17 @@ heap_inplace_update_and_unlock(Relation relation,
65076507
* [crash]
65086508
* [recovery restores datfrozenxid w/o relfrozenxid]
65096509
*
6510-
* Like in MarkBufferDirtyHint() subroutine XLogSaveBufferForHint(), copy
6511-
* the buffer to the stack before logging. Here, that facilitates a FPI
6512-
* of the post-mutation block before we accept other sessions seeing it.
6510+
* Mimic MarkBufferDirtyHint() subroutine XLogSaveBufferForHint().
6511+
* Specifically, use DELAY_CHKPT_START, and copy the buffer to the stack.
6512+
* The stack copy facilitates a FPI of the post-mutation block before we
6513+
* accept other sessions seeing it. DELAY_CHKPT_START allows us to
6514+
* XLogInsert() before MarkBufferDirty(). Since XLogSaveBufferForHint()
6515+
* can operate under BUFFER_LOCK_SHARED, it can't avoid DELAY_CHKPT_START.
6516+
* This function, however, likely could avoid it with the following order
6517+
* of operations: MarkBufferDirty(), XLogInsert(), memcpy(). Opt to use
6518+
* DELAY_CHKPT_START here, too, as a way to have fewer distinct code
6519+
* patterns to analyze. Inplace update isn't so frequent that it should
6520+
* pursue the small optimization of skipping DELAY_CHKPT_START.
65136521
*/
65146522
Assert((MyProc->delayChkptFlags & DELAY_CHKPT_START) == 0);
65156523
START_CRIT_SECTION();

src/include/storage/proc.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -110,10 +110,10 @@ extern PGDLLIMPORT int FastPathLockGroupsPerBackend;
110110
* is inserted prior to the new redo point, the corresponding data changes will
111111
* also be flushed to disk before the checkpoint can complete. (In the
112112
* extremely common case where the data being modified is in shared buffers
113-
* and we acquire an exclusive content lock on the relevant buffers before
114-
* writing WAL, this mechanism is not needed, because phase 2 will block
115-
* until we release the content lock and then flush the modified data to
116-
* disk.)
113+
* and we acquire an exclusive content lock and MarkBufferDirty() on the
114+
* relevant buffers before writing WAL, this mechanism is not needed, because
115+
* phase 2 will block until we release the content lock and then flush the
116+
* modified data to disk. See transam/README and SyncOneBuffer().)
117117
*
118118
* Setting DELAY_CHKPT_COMPLETE prevents the system from moving from phase 2
119119
* to phase 3. This is useful if we are performing a WAL-logged operation that

0 commit comments

Comments
 (0)