@@ -141,12 +141,13 @@ static void *
141
141
doExtractPageMap (void * arg )
142
142
{
143
143
xlog_thread_arg * extract_arg = (xlog_thread_arg * ) arg ;
144
+ XLogPageReadPrivate * private_data ;
144
145
XLogReaderState * xlogreader ;
145
146
XLogSegNo nextSegNo = 0 ;
146
147
char * errormsg ;
147
148
148
- xlogreader = XLogReaderAllocate ( & SimpleXLogPageRead ,
149
- & extract_arg -> private_data );
149
+ private_data = & extract_arg -> private_data ;
150
+ xlogreader = XLogReaderAllocate ( & SimpleXLogPageRead , private_data );
150
151
if (xlogreader == NULL )
151
152
elog (ERROR , "out of memory" );
152
153
@@ -158,6 +159,9 @@ doExtractPageMap(void *arg)
158
159
(uint32 ) (extract_arg -> startpoint >> 32 ),
159
160
(uint32 ) (extract_arg -> startpoint ));
160
161
162
+ /* Switch WAL segment manually below without using SimpleXLogPageRead() */
163
+ private_data -> manual_switch = true;
164
+
161
165
do
162
166
{
163
167
XLogRecord * record ;
@@ -171,23 +175,28 @@ doExtractPageMap(void *arg)
171
175
{
172
176
XLogRecPtr errptr ;
173
177
174
- /* Try to switch to the next WAL segment */
175
- if (extract_arg -> private_data .need_switch )
178
+ /*
179
+ * Try to switch to the next WAL segment. Usually
180
+ * SimpleXLogPageRead() does it by itself. But here we need to do it
181
+ * manually to support threads.
182
+ */
183
+ if (private_data -> need_switch )
176
184
{
177
- extract_arg -> private_data . need_switch = false;
185
+ private_data -> need_switch = false;
178
186
187
+ /* Critical section */
179
188
pthread_lock (& wal_segment_mutex );
180
189
Assert (nextSegNoToRead );
181
- extract_arg -> private_data . xlogsegno = nextSegNoToRead ;
190
+ private_data -> xlogsegno = nextSegNoToRead ;
182
191
nextSegNoToRead ++ ;
183
192
pthread_mutex_unlock (& wal_segment_mutex );
184
193
185
194
/* We reach the end */
186
- if (extract_arg -> private_data . xlogsegno > extract_arg -> endSegNo )
195
+ if (private_data -> xlogsegno > extract_arg -> endSegNo )
187
196
break ;
188
197
189
198
/* Adjust next record position */
190
- XLogSegNoOffsetToRecPtr (extract_arg -> private_data . xlogsegno , 0 ,
199
+ XLogSegNoOffsetToRecPtr (private_data -> xlogsegno , 0 ,
191
200
extract_arg -> startpoint );
192
201
/* Skip over the page header */
193
202
extract_arg -> startpoint = XLogFindNextRecord (xlogreader ,
@@ -217,7 +226,7 @@ doExtractPageMap(void *arg)
217
226
* start_lsn, we won't be able to build page map and PAGE backup will
218
227
* be incorrect. Stop it and throw an error.
219
228
*/
220
- PrintXLogCorruptionMsg (& extract_arg -> private_data , ERROR );
229
+ PrintXLogCorruptionMsg (private_data , ERROR );
221
230
}
222
231
223
232
extractPageInfo (xlogreader );
@@ -255,8 +264,8 @@ extractPageMap(const char *archivedir, XLogRecPtr startpoint, TimeLineID tli,
255
264
int threads_need = 0 ;
256
265
XLogSegNo endSegNo ;
257
266
bool extract_isok = true;
258
- pthread_t threads [ num_threads ] ;
259
- xlog_thread_arg thread_args [ num_threads ] ;
267
+ pthread_t * threads ;
268
+ xlog_thread_arg * thread_args ;
260
269
time_t start_time ,
261
270
end_time ;
262
271
@@ -276,6 +285,9 @@ extractPageMap(const char *archivedir, XLogRecPtr startpoint, TimeLineID tli,
276
285
nextSegNoToRead = 0 ;
277
286
time (& start_time );
278
287
288
+ threads = (pthread_t * ) palloc (sizeof (pthread_t ) * num_threads );
289
+ thread_args = (xlog_thread_arg * ) palloc (sizeof (xlog_thread_arg )* num_threads );
290
+
279
291
/*
280
292
* Initialize thread args.
281
293
*
@@ -286,7 +298,6 @@ extractPageMap(const char *archivedir, XLogRecPtr startpoint, TimeLineID tli,
286
298
{
287
299
InitXLogPageRead (& thread_args [i ].private_data , archivedir , tli , false);
288
300
thread_args [i ].thread_num = i ;
289
- thread_args [i ].private_data .manual_switch = true;
290
301
291
302
thread_args [i ].startpoint = startpoint ;
292
303
thread_args [i ].endpoint = endpoint ;
@@ -327,6 +338,9 @@ extractPageMap(const char *archivedir, XLogRecPtr startpoint, TimeLineID tli,
327
338
extract_isok = false;
328
339
}
329
340
341
+ pfree (threads );
342
+ pfree (thread_args );
343
+
330
344
time (& end_time );
331
345
if (extract_isok )
332
346
elog (LOG , "Pagemap compiled, time elapsed %.0f sec" ,
@@ -700,6 +714,10 @@ SimpleXLogPageRead(XLogReaderState *xlogreader, XLogRecPtr targetPagePtr,
700
714
if (!XLByteInSeg (targetPagePtr , private_data -> xlogsegno ))
701
715
{
702
716
CleanupXLogPageRead (xlogreader );
717
+ /*
718
+ * Do not switch to next WAL segment in this function. Currently it is
719
+ * manually switched only in doExtractPageMap().
720
+ */
703
721
if (private_data -> manual_switch )
704
722
{
705
723
private_data -> need_switch = true;
@@ -709,6 +727,7 @@ SimpleXLogPageRead(XLogReaderState *xlogreader, XLogRecPtr targetPagePtr,
709
727
710
728
XLByteToSeg (targetPagePtr , private_data -> xlogsegno );
711
729
730
+ /* Try to switch to the next WAL segment */
712
731
if (!private_data -> xlogexists )
713
732
{
714
733
char xlogfname [MAXFNAMELEN ];
0 commit comments