aboutsummaryrefslogtreecommitdiff
path: root/src/backend/storage/buffer/bufmgr.c
diff options
context:
space:
mode:
authorNoah Misch <noah@leadboat.com>2024-07-20 04:22:12 -0700
committerNoah Misch <noah@leadboat.com>2024-07-20 04:22:12 -0700
commit8720a15e9ab121e49174d889eaeafae8ac89de7b (patch)
treeb06b632c4bf8bd0f60d9b97c618a3cb656132e05 /src/backend/storage/buffer/bufmgr.c
parenta858be17c3f85a2ce3ad5e3073c14ab948b85079 (diff)
downloadpostgresql-8720a15e9ab121e49174d889eaeafae8ac89de7b.tar.gz
postgresql-8720a15e9ab121e49174d889eaeafae8ac89de7b.zip
Use read streams in CREATE DATABASE when STRATEGY=WAL_LOG.
While this doesn't significantly change runtime now, it arranges for STRATEGY=WAL_LOG to benefit automatically from future optimizations to the read_stream subsystem. For large tables in the template database, this does read 16x as many bytes per system call. Platforms with high per-call overhead, if any, may see an immediate benefit. Nazir Bilal Yavuz Discussion: https://postgr.es/m/CAN55FZ0JKL6vk1xQp6rfOXiNFV1u1H0tJDPPGHWoiO3ea2Wc=A@mail.gmail.com
Diffstat (limited to 'src/backend/storage/buffer/bufmgr.c')
-rw-r--r--src/backend/storage/buffer/bufmgr.c53
1 files changed, 49 insertions, 4 deletions
diff --git a/src/backend/storage/buffer/bufmgr.c b/src/backend/storage/buffer/bufmgr.c
index bdb36e5a30e..a6aeecdf534 100644
--- a/src/backend/storage/buffer/bufmgr.c
+++ b/src/backend/storage/buffer/bufmgr.c
@@ -54,6 +54,7 @@
#include "storage/ipc.h"
#include "storage/lmgr.h"
#include "storage/proc.h"
+#include "storage/read_stream.h"
#include "storage/smgr.h"
#include "storage/standby.h"
#include "utils/memdebug.h"
@@ -135,6 +136,33 @@ typedef struct SMgrSortArray
SMgrRelation srel;
} SMgrSortArray;
+/*
+ * Helper struct for read stream object used in
+ * RelationCopyStorageUsingBuffer() function.
+ */
+struct copy_storage_using_buffer_read_stream_private
+{
+ BlockNumber blocknum;
+ BlockNumber last_block;
+};
+
+/*
+ * Callback function to get next block for read stream object used in
+ * RelationCopyStorageUsingBuffer() function.
+ */
+static BlockNumber
+copy_storage_using_buffer_read_stream_next_block(ReadStream *stream,
+ void *callback_private_data,
+ void *per_buffer_data)
+{
+ struct copy_storage_using_buffer_read_stream_private *p = callback_private_data;
+
+ if (p->blocknum < p->last_block)
+ return p->blocknum++;
+
+ return InvalidBlockNumber;
+}
+
/* GUC variables */
bool zero_damaged_pages = false;
int bgwriter_lru_maxpages = 100;
@@ -4685,6 +4713,9 @@ RelationCopyStorageUsingBuffer(RelFileLocator srclocator,
PGIOAlignedBlock buf;
BufferAccessStrategy bstrategy_src;
BufferAccessStrategy bstrategy_dst;
+ struct copy_storage_using_buffer_read_stream_private p;
+ ReadStream *src_stream;
+ SMgrRelation src_smgr;
/*
* In general, we want to write WAL whenever wal_level > 'minimal', but we
@@ -4713,19 +4744,31 @@ RelationCopyStorageUsingBuffer(RelFileLocator srclocator,
bstrategy_src = GetAccessStrategy(BAS_BULKREAD);
bstrategy_dst = GetAccessStrategy(BAS_BULKWRITE);
+ /* Initalize streaming read */
+ p.blocknum = 0;
+ p.last_block = nblocks;
+ src_smgr = smgropen(srclocator, INVALID_PROC_NUMBER);
+ src_stream = read_stream_begin_smgr_relation(READ_STREAM_FULL,
+ bstrategy_src,
+ src_smgr,
+ permanent ? RELPERSISTENCE_PERMANENT : RELPERSISTENCE_UNLOGGED,
+ forkNum,
+ copy_storage_using_buffer_read_stream_next_block,
+ &p,
+ 0);
+
/* Iterate over each block of the source relation file. */
for (blkno = 0; blkno < nblocks; blkno++)
{
CHECK_FOR_INTERRUPTS();
/* Read block from source relation. */
- srcBuf = ReadBufferWithoutRelcache(srclocator, forkNum, blkno,
- RBM_NORMAL, bstrategy_src,
- permanent);
+ srcBuf = read_stream_next_buffer(src_stream, NULL);
LockBuffer(srcBuf, BUFFER_LOCK_SHARE);
srcPage = BufferGetPage(srcBuf);
- dstBuf = ReadBufferWithoutRelcache(dstlocator, forkNum, blkno,
+ dstBuf = ReadBufferWithoutRelcache(dstlocator, forkNum,
+ BufferGetBlockNumber(srcBuf),
RBM_ZERO_AND_LOCK, bstrategy_dst,
permanent);
dstPage = BufferGetPage(dstBuf);
@@ -4745,6 +4788,8 @@ RelationCopyStorageUsingBuffer(RelFileLocator srclocator,
UnlockReleaseBuffer(dstBuf);
UnlockReleaseBuffer(srcBuf);
}
+ Assert(read_stream_next_buffer(src_stream, NULL) == InvalidBuffer);
+ read_stream_end(src_stream);
FreeAccessStrategy(bstrategy_src);
FreeAccessStrategy(bstrategy_dst);