@@ -811,17 +811,13 @@ static XLogSegNo openLogSegNo = 0;
811
811
* These variables are used similarly to the ones above, but for reading
812
812
* the XLOG. Note, however, that readOff generally represents the offset
813
813
* of the page just read, not the seek position of the FD itself, which
814
- * will be just past that page. readLen indicates how much of the current
815
- * page has been read into readBuf, and readSource indicates where we got
816
- * the currently open file from.
814
+ * will be just past that page. readSource indicates where we got the
815
+ * currently open file from.
817
816
* Note: we could use Reserve/ReleaseExternalFD to track consumption of
818
817
* this FD too; but it doesn't currently seem worthwhile, since the XLOG is
819
818
* not read by general-purpose sessions.
820
819
*/
821
820
static int readFile = -1 ;
822
- static XLogSegNo readSegNo = 0 ;
823
- static uint32 readOff = 0 ;
824
- static uint32 readLen = 0 ;
825
821
static XLogSource readSource = XLOG_FROM_ANY ;
826
822
827
823
/*
@@ -838,13 +834,6 @@ static XLogSource currentSource = XLOG_FROM_ANY;
838
834
static bool lastSourceFailed = false;
839
835
static bool pendingWalRcvRestart = false;
840
836
841
- typedef struct XLogPageReadPrivate
842
- {
843
- int emode ;
844
- bool fetching_ckpt ; /* are we fetching a checkpoint record? */
845
- bool randAccess ;
846
- } XLogPageReadPrivate ;
847
-
848
837
/*
849
838
* These variables track when we last obtained some WAL data to process,
850
839
* and where we got it from. (XLogReceiptSource is initially the same as
@@ -920,10 +909,12 @@ static bool InstallXLogFileSegment(XLogSegNo *segno, char *tmppath,
920
909
static int XLogFileRead (XLogSegNo segno , int emode , TimeLineID tli ,
921
910
XLogSource source , bool notfoundOk );
922
911
static int XLogFileReadAnyTLI (XLogSegNo segno , int emode , XLogSource source );
923
- static int XLogPageRead (XLogReaderState * xlogreader , XLogRecPtr targetPagePtr ,
924
- int reqLen , XLogRecPtr targetRecPtr , char * readBuf );
912
+ static bool XLogPageRead (XLogReaderState * state ,
913
+ bool fetching_ckpt , int emode , bool randAccess );
925
914
static bool WaitForWALToBecomeAvailable (XLogRecPtr RecPtr , bool randAccess ,
926
- bool fetching_ckpt , XLogRecPtr tliRecPtr );
915
+ bool fetching_ckpt ,
916
+ XLogRecPtr tliRecPtr ,
917
+ XLogSegNo readSegNo );
927
918
static int emode_for_corrupt_record (int emode , XLogRecPtr RecPtr );
928
919
static void XLogFileClose (void );
929
920
static void PreallocXlogFiles (XLogRecPtr endptr );
@@ -1234,8 +1225,7 @@ XLogInsertRecord(XLogRecData *rdata,
1234
1225
appendBinaryStringInfo (& recordBuf , rdata -> data , rdata -> len );
1235
1226
1236
1227
if (!debug_reader )
1237
- debug_reader = XLogReaderAllocate (wal_segment_size , NULL ,
1238
- XL_ROUTINE (), NULL );
1228
+ debug_reader = XLogReaderAllocate (wal_segment_size , NULL , NULL );
1239
1229
1240
1230
if (!debug_reader )
1241
1231
{
@@ -4373,21 +4363,24 @@ ReadRecord(XLogReaderState *xlogreader, int emode,
4373
4363
bool fetching_ckpt )
4374
4364
{
4375
4365
XLogRecord * record ;
4376
- XLogPageReadPrivate * private = (XLogPageReadPrivate * ) xlogreader -> private_data ;
4377
-
4378
- /* Pass through parameters to XLogPageRead */
4379
- private -> fetching_ckpt = fetching_ckpt ;
4380
- private -> emode = emode ;
4381
- private -> randAccess = (xlogreader -> ReadRecPtr == InvalidXLogRecPtr );
4366
+ bool randAccess = (xlogreader -> ReadRecPtr == InvalidXLogRecPtr );
4382
4367
4383
4368
/* This is the first attempt to read this page. */
4384
4369
lastSourceFailed = false;
4385
4370
4386
4371
for (;;)
4387
4372
{
4388
4373
char * errormsg ;
4374
+ XLogReadRecordResult result ;
4375
+
4376
+ while ((result = XLogReadRecord (xlogreader , & record , & errormsg ))
4377
+ == XLREAD_NEED_DATA )
4378
+ {
4379
+ if (!XLogPageRead (xlogreader , fetching_ckpt , emode , randAccess ))
4380
+ break ;
4381
+
4382
+ }
4389
4383
4390
- record = XLogReadRecord (xlogreader , & errormsg );
4391
4384
ReadRecPtr = xlogreader -> ReadRecPtr ;
4392
4385
EndRecPtr = xlogreader -> EndRecPtr ;
4393
4386
if (record == NULL )
@@ -6457,7 +6450,6 @@ StartupXLOG(void)
6457
6450
bool backupFromStandby = false;
6458
6451
DBState dbstate_at_startup ;
6459
6452
XLogReaderState * xlogreader ;
6460
- XLogPageReadPrivate private ;
6461
6453
bool promoted = false;
6462
6454
struct stat st ;
6463
6455
@@ -6616,13 +6608,9 @@ StartupXLOG(void)
6616
6608
OwnLatch (& XLogCtl -> recoveryWakeupLatch );
6617
6609
6618
6610
/* Set up XLOG reader facility */
6619
- MemSet (& private , 0 , sizeof (XLogPageReadPrivate ));
6620
6611
xlogreader =
6621
- XLogReaderAllocate (wal_segment_size , NULL ,
6622
- XL_ROUTINE (.page_read = & XLogPageRead ,
6623
- .segment_open = NULL ,
6624
- .segment_close = wal_segment_close ),
6625
- & private );
6612
+ XLogReaderAllocate (wal_segment_size , NULL , wal_segment_close );
6613
+
6626
6614
if (!xlogreader )
6627
6615
ereport (ERROR ,
6628
6616
(errcode (ERRCODE_OUT_OF_MEMORY ),
@@ -7819,7 +7807,8 @@ StartupXLOG(void)
7819
7807
XLogRecPtr pageBeginPtr ;
7820
7808
7821
7809
pageBeginPtr = EndOfLog - (EndOfLog % XLOG_BLCKSZ );
7822
- Assert (readOff == XLogSegmentOffset (pageBeginPtr , wal_segment_size ));
7810
+ Assert (XLogSegmentOffset (xlogreader -> readPagePtr , wal_segment_size ) ==
7811
+ XLogSegmentOffset (pageBeginPtr , wal_segment_size ));
7823
7812
7824
7813
firstIdx = XLogRecPtrToBufIdx (EndOfLog );
7825
7814
@@ -12107,13 +12096,15 @@ CancelBackup(void)
12107
12096
* XLogPageRead() to try fetching the record from another source, or to
12108
12097
* sleep and retry.
12109
12098
*/
12110
- static int
12111
- XLogPageRead (XLogReaderState * xlogreader , XLogRecPtr targetPagePtr , int reqLen ,
12112
- XLogRecPtr targetRecPtr , char * readBuf )
12113
- {
12114
- XLogPageReadPrivate * private =
12115
- (XLogPageReadPrivate * ) xlogreader -> private_data ;
12116
- int emode = private -> emode ;
12099
+ static bool
12100
+ XLogPageRead (XLogReaderState * state ,
12101
+ bool fetching_ckpt , int emode , bool randAccess )
12102
+ {
12103
+ char * readBuf = state -> readBuf ;
12104
+ XLogRecPtr targetPagePtr = state -> readPagePtr ;
12105
+ int reqLen = state -> reqLen ;
12106
+ int readLen = 0 ;
12107
+ XLogRecPtr targetRecPtr = state -> ReadRecPtr ;
12117
12108
uint32 targetPageOff ;
12118
12109
XLogSegNo targetSegNo PG_USED_FOR_ASSERTS_ONLY ;
12119
12110
int r ;
@@ -12126,18 +12117,18 @@ XLogPageRead(XLogReaderState *xlogreader, XLogRecPtr targetPagePtr, int reqLen,
12126
12117
* is not in the currently open one.
12127
12118
*/
12128
12119
if (readFile >= 0 &&
12129
- !XLByteInSeg (targetPagePtr , readSegNo , wal_segment_size ))
12120
+ !XLByteInSeg (targetPagePtr , state -> seg . ws_segno , wal_segment_size ))
12130
12121
{
12131
12122
/*
12132
12123
* Request a restartpoint if we've replayed too much xlog since the
12133
12124
* last one.
12134
12125
*/
12135
12126
if (bgwriterLaunched )
12136
12127
{
12137
- if (XLogCheckpointNeeded (readSegNo ))
12128
+ if (XLogCheckpointNeeded (state -> seg . ws_segno ))
12138
12129
{
12139
12130
(void ) GetRedoRecPtr ();
12140
- if (XLogCheckpointNeeded (readSegNo ))
12131
+ if (XLogCheckpointNeeded (state -> seg . ws_segno ))
12141
12132
RequestCheckpoint (CHECKPOINT_CAUSE_XLOG );
12142
12133
}
12143
12134
}
@@ -12147,7 +12138,7 @@ XLogPageRead(XLogReaderState *xlogreader, XLogRecPtr targetPagePtr, int reqLen,
12147
12138
readSource = XLOG_FROM_ANY ;
12148
12139
}
12149
12140
12150
- XLByteToSeg (targetPagePtr , readSegNo , wal_segment_size );
12141
+ XLByteToSeg (targetPagePtr , state -> seg . ws_segno , wal_segment_size );
12151
12142
12152
12143
retry :
12153
12144
/* See if we need to retrieve more data */
@@ -12156,17 +12147,15 @@ XLogPageRead(XLogReaderState *xlogreader, XLogRecPtr targetPagePtr, int reqLen,
12156
12147
flushedUpto < targetPagePtr + reqLen ))
12157
12148
{
12158
12149
if (!WaitForWALToBecomeAvailable (targetPagePtr + reqLen ,
12159
- private -> randAccess ,
12160
- private -> fetching_ckpt ,
12161
- targetRecPtr ))
12150
+ randAccess , fetching_ckpt ,
12151
+ targetRecPtr , state -> seg .ws_segno ))
12162
12152
{
12163
12153
if (readFile >= 0 )
12164
12154
close (readFile );
12165
12155
readFile = -1 ;
12166
- readLen = 0 ;
12167
12156
readSource = XLOG_FROM_ANY ;
12168
-
12169
- return -1 ;
12157
+ XLogReaderSetInputData ( state , -1 );
12158
+ return false ;
12170
12159
}
12171
12160
}
12172
12161
@@ -12193,40 +12182,36 @@ XLogPageRead(XLogReaderState *xlogreader, XLogRecPtr targetPagePtr, int reqLen,
12193
12182
else
12194
12183
readLen = XLOG_BLCKSZ ;
12195
12184
12196
- /* Read the requested page */
12197
- readOff = targetPageOff ;
12198
-
12199
12185
pgstat_report_wait_start (WAIT_EVENT_WAL_READ );
12200
- r = pg_pread (readFile , readBuf , XLOG_BLCKSZ , (off_t ) readOff );
12186
+ r = pg_pread (readFile , readBuf , XLOG_BLCKSZ , (off_t ) targetPageOff );
12201
12187
if (r != XLOG_BLCKSZ )
12202
12188
{
12203
12189
char fname [MAXFNAMELEN ];
12204
12190
int save_errno = errno ;
12205
12191
12206
12192
pgstat_report_wait_end ();
12207
- XLogFileName (fname , curFileTLI , readSegNo , wal_segment_size );
12193
+ XLogFileName (fname , curFileTLI , state -> seg . ws_segno , wal_segment_size );
12208
12194
if (r < 0 )
12209
12195
{
12210
12196
errno = save_errno ;
12211
12197
ereport (emode_for_corrupt_record (emode , targetPagePtr + reqLen ),
12212
12198
(errcode_for_file_access (),
12213
12199
errmsg ("could not read from log segment %s, offset %u: %m" ,
12214
- fname , readOff )));
12200
+ fname , targetPageOff )));
12215
12201
}
12216
12202
else
12217
12203
ereport (emode_for_corrupt_record (emode , targetPagePtr + reqLen ),
12218
12204
(errcode (ERRCODE_DATA_CORRUPTED ),
12219
12205
errmsg ("could not read from log segment %s, offset %u: read %d of %zu" ,
12220
- fname , readOff , r , (Size ) XLOG_BLCKSZ )));
12206
+ fname , targetPageOff , r , (Size ) XLOG_BLCKSZ )));
12221
12207
goto next_record_is_invalid ;
12222
12208
}
12223
12209
pgstat_report_wait_end ();
12224
12210
12225
- Assert (targetSegNo == readSegNo );
12226
- Assert (targetPageOff == readOff );
12227
- Assert (reqLen <= readLen );
12211
+ Assert (targetSegNo == state -> seg .ws_segno );
12212
+ Assert (readLen >= reqLen );
12228
12213
12229
- xlogreader -> seg .ws_tli = curFileTLI ;
12214
+ state -> seg .ws_tli = curFileTLI ;
12230
12215
12231
12216
/*
12232
12217
* Check the page header immediately, so that we can retry immediately if
@@ -12254,29 +12239,31 @@ XLogPageRead(XLogReaderState *xlogreader, XLogRecPtr targetPagePtr, int reqLen,
12254
12239
* Validating the page header is cheap enough that doing it twice
12255
12240
* shouldn't be a big deal from a performance point of view.
12256
12241
*/
12257
- if (!XLogReaderValidatePageHeader (xlogreader , targetPagePtr , readBuf ))
12242
+ if (!XLogReaderValidatePageHeader (state , targetPagePtr , readBuf ))
12258
12243
{
12259
- /* reset any error XLogReaderValidatePageHeader () might have set */
12260
- xlogreader -> errormsg_buf [0 ] = '\0' ;
12244
+ /* reset any error StateValidatePageHeader () might have set */
12245
+ state -> errormsg_buf [0 ] = '\0' ;
12261
12246
goto next_record_is_invalid ;
12262
12247
}
12263
12248
12264
- return readLen ;
12249
+ Assert (state -> readPagePtr == targetPagePtr );
12250
+ XLogReaderSetInputData (state , readLen );
12251
+ return true;
12265
12252
12266
12253
next_record_is_invalid :
12267
12254
lastSourceFailed = true;
12268
12255
12269
12256
if (readFile >= 0 )
12270
12257
close (readFile );
12271
12258
readFile = -1 ;
12272
- readLen = 0 ;
12273
12259
readSource = XLOG_FROM_ANY ;
12274
12260
12275
12261
/* In standby-mode, keep trying */
12276
12262
if (StandbyMode )
12277
12263
goto retry ;
12278
- else
12279
- return -1 ;
12264
+
12265
+ XLogReaderSetInputData (state , -1 );
12266
+ return false;
12280
12267
}
12281
12268
12282
12269
/*
@@ -12307,7 +12294,8 @@ XLogPageRead(XLogReaderState *xlogreader, XLogRecPtr targetPagePtr, int reqLen,
12307
12294
*/
12308
12295
static bool
12309
12296
WaitForWALToBecomeAvailable (XLogRecPtr RecPtr , bool randAccess ,
12310
- bool fetching_ckpt , XLogRecPtr tliRecPtr )
12297
+ bool fetching_ckpt , XLogRecPtr tliRecPtr ,
12298
+ XLogSegNo readSegNo )
12311
12299
{
12312
12300
static TimestampTz last_fail_time = 0 ;
12313
12301
TimestampTz now ;
0 commit comments