@@ -45,7 +45,7 @@ static char xlogfpath[MAXPGPATH];
4545typedef struct XLogPageReadPrivate
4646{
4747 const char * datadir ;
48- TimeLineID tli ;
48+ int tliIndex ;
4949} XLogPageReadPrivate ;
5050
5151static int SimpleXLogPageRead (XLogReaderState * xlogreader ,
@@ -55,11 +55,11 @@ static int SimpleXLogPageRead(XLogReaderState *xlogreader,
5555
5656/*
5757 * Read WAL from the datadir/pg_xlog, starting from 'startpoint' on timeline
58- * 'tli' , until 'endpoint'. Make note of the data blocks touched by the WAL
59- * records, and return them in a page map.
58+ * index 'tliIndex' in target timeline history , until 'endpoint'. Make note of
59+ * the data blocks touched by the WAL records, and return them in a page map.
6060 */
6161void
62- extractPageMap (const char * datadir , XLogRecPtr startpoint , TimeLineID tli ,
62+ extractPageMap (const char * datadir , XLogRecPtr startpoint , int tliIndex ,
6363 XLogRecPtr endpoint )
6464{
6565 XLogRecord * record ;
@@ -68,7 +68,7 @@ extractPageMap(const char *datadir, XLogRecPtr startpoint, TimeLineID tli,
6868 XLogPageReadPrivate private ;
6969
7070 private .datadir = datadir ;
71- private .tli = tli ;
71+ private .tliIndex = tliIndex ;
7272 xlogreader = XLogReaderAllocate (& SimpleXLogPageRead , & private );
7373 if (xlogreader == NULL )
7474 pg_fatal ("out of memory\n" );
@@ -112,7 +112,7 @@ extractPageMap(const char *datadir, XLogRecPtr startpoint, TimeLineID tli,
112112 * doing anything with the record itself.
113113 */
114114XLogRecPtr
115- readOneRecord (const char * datadir , XLogRecPtr ptr , TimeLineID tli )
115+ readOneRecord (const char * datadir , XLogRecPtr ptr , int tliIndex )
116116{
117117 XLogRecord * record ;
118118 XLogReaderState * xlogreader ;
@@ -121,7 +121,7 @@ readOneRecord(const char *datadir, XLogRecPtr ptr, TimeLineID tli)
121121 XLogRecPtr endptr ;
122122
123123 private .datadir = datadir ;
124- private .tli = tli ;
124+ private .tliIndex = tliIndex ;
125125 xlogreader = XLogReaderAllocate (& SimpleXLogPageRead , & private );
126126 if (xlogreader == NULL )
127127 pg_fatal ("out of memory\n" );
@@ -152,7 +152,7 @@ readOneRecord(const char *datadir, XLogRecPtr ptr, TimeLineID tli)
152152 * Find the previous checkpoint preceding given WAL position.
153153 */
154154void
155- findLastCheckpoint (const char * datadir , XLogRecPtr forkptr , TimeLineID tli ,
155+ findLastCheckpoint (const char * datadir , XLogRecPtr forkptr , int tliIndex ,
156156 XLogRecPtr * lastchkptrec , TimeLineID * lastchkpttli ,
157157 XLogRecPtr * lastchkptredo )
158158{
@@ -173,7 +173,7 @@ findLastCheckpoint(const char *datadir, XLogRecPtr forkptr, TimeLineID tli,
173173 forkptr += (forkptr % XLogSegSize == 0 ) ? SizeOfXLogLongPHD : SizeOfXLogShortPHD ;
174174
175175 private .datadir = datadir ;
176- private .tli = tli ;
176+ private .tliIndex = tliIndex ;
177177 xlogreader = XLogReaderAllocate (& SimpleXLogPageRead , & private );
178178 if (xlogreader == NULL )
179179 pg_fatal ("out of memory\n" );
@@ -236,9 +236,11 @@ SimpleXLogPageRead(XLogReaderState *xlogreader, XLogRecPtr targetPagePtr,
236236{
237237 XLogPageReadPrivate * private = (XLogPageReadPrivate * ) xlogreader -> private_data ;
238238 uint32 targetPageOff ;
239- XLogSegNo targetSegNo PG_USED_FOR_ASSERTS_ONLY ;
239+ XLogRecPtr targetSegEnd ;
240+ XLogSegNo targetSegNo ;
240241
241242 XLByteToSeg (targetPagePtr , targetSegNo );
243+ XLogSegNoOffsetToRecPtr (targetSegNo + 1 , 0 , targetSegEnd );
242244 targetPageOff = targetPagePtr % XLogSegSize ;
243245
244246 /*
@@ -257,7 +259,20 @@ SimpleXLogPageRead(XLogReaderState *xlogreader, XLogRecPtr targetPagePtr,
257259 {
258260 char xlogfname [MAXFNAMELEN ];
259261
260- XLogFileName (xlogfname , private -> tli , xlogreadsegno );
262+ /*
263+ * Since incomplete segments are copied into next timelines, switch to
264+ * the timeline holding the required segment. Assuming this scan can be
265+ * done both forward and backward, consider also switching timeline
266+ * accordingly.
267+ */
268+ while (private -> tliIndex < targetNentries - 1 &&
269+ targetHistory [private -> tliIndex ].end < targetSegEnd )
270+ private -> tliIndex ++ ;
271+ while (private -> tliIndex > 0 &&
272+ targetHistory [private -> tliIndex ].begin >= targetSegEnd )
273+ private -> tliIndex -- ;
274+
275+ XLogFileName (xlogfname , targetHistory [private -> tliIndex ].tli , xlogreadsegno );
261276
262277 snprintf (xlogfpath , MAXPGPATH , "%s/" XLOGDIR "/%s" , private -> datadir , xlogfname );
263278
@@ -293,7 +308,7 @@ SimpleXLogPageRead(XLogReaderState *xlogreader, XLogRecPtr targetPagePtr,
293308
294309 Assert (targetSegNo == xlogreadsegno );
295310
296- * pageTLI = private -> tli ;
311+ * pageTLI = targetHistory [ private -> tliIndex ]. tli ;
297312 return XLOG_BLCKSZ ;
298313}
299314
0 commit comments