From ee48966af6dcf6e2d18279faab17bbf8944f903e Mon Sep 17 00:00:00 2001 From: ChangAo Chen Date: Wed, 3 Jun 2026 19:01:17 +0800 Subject: [PATCH v1] Use streaming read I/O when enabling data checksums online --- src/backend/postmaster/datachecksum_state.c | 35 +++++++++++++++++++-- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/src/backend/postmaster/datachecksum_state.c b/src/backend/postmaster/datachecksum_state.c index a49a31d1281..2b793b082d8 100644 --- a/src/backend/postmaster/datachecksum_state.c +++ b/src/backend/postmaster/datachecksum_state.c @@ -210,6 +210,7 @@ #include "storage/lmgr.h" #include "storage/lwlock.h" #include "storage/procarray.h" +#include "storage/read_stream.h" #include "storage/smgr.h" #include "storage/subsystems.h" #include "tcop/tcopprot.h" @@ -654,6 +655,9 @@ ProcessSingleRelationFork(Relation reln, ForkNumber forkNum, BufferAccessStrateg BlockNumber numblocks = RelationGetNumberOfBlocksInFork(reln, forkNum); char activity[NAMEDATALEN * 2 + 128]; char *relns; + bool success = true; + BlockRangeReadStreamPrivate p; + ReadStream *stream; relns = get_namespace_name(RelationGetNamespace(reln)); @@ -670,9 +674,26 @@ ProcessSingleRelationFork(Relation reln, ForkNumber forkNum, BufferAccessStrateg * start, which is safe since new blocks are created with checksums set * already due to the state being "inprogress-on". */ + p.current_blocknum = 0; + p.last_exclusive = numblocks; + + /* + * It is safe to use batchmode as block_range_read_stream_cb takes no + * locks. + */ + stream = read_stream_begin_relation(READ_STREAM_MAINTENANCE | + READ_STREAM_FULL | + READ_STREAM_USE_BATCHING, + strategy, + reln, + forkNum, + block_range_read_stream_cb, + &p, + 0); + for (BlockNumber blknum = 0; blknum < numblocks; blknum++) { - Buffer buf = ReadBufferExtended(reln, forkNum, blknum, RBM_NORMAL, strategy); + Buffer buf = read_stream_next_buffer(stream, NULL); /* Need to get an exclusive lock to mark the buffer as dirty */ LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE); @@ -715,7 +736,10 @@ ProcessSingleRelationFork(Relation reln, ForkNumber forkNum, BufferAccessStrateg LWLockRelease(DataChecksumsWorkerLock); if (abort_requested) - return false; + { + success = false; + break; + } /* update the block counter */ pgstat_progress_update_param(PROGRESS_DATACHECKSUMS_BLOCKS_DONE, @@ -728,7 +752,12 @@ ProcessSingleRelationFork(Relation reln, ForkNumber forkNum, BufferAccessStrateg vacuum_delay_point(false); } - return true; + if (success) + Assert(read_stream_next_buffer(stream, NULL) == InvalidBuffer); + + read_stream_end(stream); + + return success; } /* -- 2.34.1