5454#include "storage/ipc.h"
5555#include "storage/lmgr.h"
5656#include "storage/proc.h"
57+ #include "storage/read_stream.h"
5758#include "storage/smgr.h"
5859#include "storage/standby.h"
5960#include "utils/memdebug.h"
@@ -135,6 +136,33 @@ typedef struct SMgrSortArray
135136 SMgrRelation srel ;
136137} SMgrSortArray ;
137138
139+ /*
140+ * Helper struct for read stream object used in
141+ * RelationCopyStorageUsingBuffer() function.
142+ */
143+ struct copy_storage_using_buffer_read_stream_private
144+ {
145+ BlockNumber blocknum ;
146+ BlockNumber last_block ;
147+ };
148+
149+ /*
150+ * Callback function to get next block for read stream object used in
151+ * RelationCopyStorageUsingBuffer() function.
152+ */
153+ static BlockNumber
154+ copy_storage_using_buffer_read_stream_next_block (ReadStream * stream ,
155+ void * callback_private_data ,
156+ void * per_buffer_data )
157+ {
158+ struct copy_storage_using_buffer_read_stream_private * p = callback_private_data ;
159+
160+ if (p -> blocknum < p -> last_block )
161+ return p -> blocknum ++ ;
162+
163+ return InvalidBlockNumber ;
164+ }
165+
138166/* GUC variables */
139167bool zero_damaged_pages = false;
140168int bgwriter_lru_maxpages = 100 ;
@@ -4685,6 +4713,9 @@ RelationCopyStorageUsingBuffer(RelFileLocator srclocator,
46854713 PGIOAlignedBlock buf ;
46864714 BufferAccessStrategy bstrategy_src ;
46874715 BufferAccessStrategy bstrategy_dst ;
4716+ struct copy_storage_using_buffer_read_stream_private p ;
4717+ ReadStream * src_stream ;
4718+ SMgrRelation src_smgr ;
46884719
46894720 /*
46904721 * In general, we want to write WAL whenever wal_level > 'minimal', but we
@@ -4713,19 +4744,31 @@ RelationCopyStorageUsingBuffer(RelFileLocator srclocator,
47134744 bstrategy_src = GetAccessStrategy (BAS_BULKREAD );
47144745 bstrategy_dst = GetAccessStrategy (BAS_BULKWRITE );
47154746
4747+ /* Initalize streaming read */
4748+ p .blocknum = 0 ;
4749+ p .last_block = nblocks ;
4750+ src_smgr = smgropen (srclocator , INVALID_PROC_NUMBER );
4751+ src_stream = read_stream_begin_smgr_relation (READ_STREAM_FULL ,
4752+ bstrategy_src ,
4753+ src_smgr ,
4754+ permanent ? RELPERSISTENCE_PERMANENT : RELPERSISTENCE_UNLOGGED ,
4755+ forkNum ,
4756+ copy_storage_using_buffer_read_stream_next_block ,
4757+ & p ,
4758+ 0 );
4759+
47164760 /* Iterate over each block of the source relation file. */
47174761 for (blkno = 0 ; blkno < nblocks ; blkno ++ )
47184762 {
47194763 CHECK_FOR_INTERRUPTS ();
47204764
47214765 /* Read block from source relation. */
4722- srcBuf = ReadBufferWithoutRelcache (srclocator , forkNum , blkno ,
4723- RBM_NORMAL , bstrategy_src ,
4724- permanent );
4766+ srcBuf = read_stream_next_buffer (src_stream , NULL );
47254767 LockBuffer (srcBuf , BUFFER_LOCK_SHARE );
47264768 srcPage = BufferGetPage (srcBuf );
47274769
4728- dstBuf = ReadBufferWithoutRelcache (dstlocator , forkNum , blkno ,
4770+ dstBuf = ReadBufferWithoutRelcache (dstlocator , forkNum ,
4771+ BufferGetBlockNumber (srcBuf ),
47294772 RBM_ZERO_AND_LOCK , bstrategy_dst ,
47304773 permanent );
47314774 dstPage = BufferGetPage (dstBuf );
@@ -4745,6 +4788,8 @@ RelationCopyStorageUsingBuffer(RelFileLocator srclocator,
47454788 UnlockReleaseBuffer (dstBuf );
47464789 UnlockReleaseBuffer (srcBuf );
47474790 }
4791+ Assert (read_stream_next_buffer (src_stream , NULL ) == InvalidBuffer );
4792+ read_stream_end (src_stream );
47484793
47494794 FreeAccessStrategy (bstrategy_src );
47504795 FreeAccessStrategy (bstrategy_dst );
0 commit comments