@@ -860,6 +860,18 @@ InitXLogPageRead(XLogReaderData *reader_data, const char *archivedir,
860860return xlogreader ;
861861}
862862
863+ /*
864+ * Comparison function to sort xlog_thread_arg array.
865+ */
866+ static int
867+ xlog_thread_arg_comp (const void * a1 ,const void * a2 )
868+ {
869+ const xlog_thread_arg * arg1 = a1 ;
870+ const xlog_thread_arg * arg2 = a2 ;
871+
872+ return arg1 -> reader_data .xlogsegno - arg2 -> reader_data .xlogsegno ;
873+ }
874+
863875/*
864876 * Run WAL processing routines using threads. Start from startpoint up to
865877 * endpoint. It is possible to send zero endpoint, threads will read WAL
@@ -877,7 +889,6 @@ RunXLogThreads(const char *archivedir, time_t target_time,
877889int i ;
878890int threads_need = 0 ;
879891XLogSegNo endSegNo = 0 ;
880- XLogSegNo errorSegNo = 0 ;
881892bool result = true;
882893
883894if (!XRecOffIsValid (startpoint ))
@@ -956,28 +967,27 @@ RunXLogThreads(const char *archivedir, time_t target_time,
956967result = false;
957968}
958969
970+ /* Release threads here, use thread_args only below */
971+ pfree (threads );
972+ threads = NULL ;
973+
959974if (last_rec )
975+ {
976+ /*
977+ * We need to sort xlog_thread_arg array by xlogsegno to return latest
978+ * possible record up to which restore is possible. We need to sort to
979+ * detect failed thread between start segment and target segment.
980+ *
981+ * Loop stops on first failed thread.
982+ */
983+ if (threads_need > 1 )
984+ qsort ((void * )thread_args ,threads_need ,sizeof (xlog_thread_arg ),
985+ xlog_thread_arg_comp );
986+
960987for (i = 0 ;i < threads_need ;i ++ )
961988{
962989XLogRecTarget * cur_rec ;
963990
964- if (thread_args [i ].ret != 0 )
965- {
966- /*
967- * Save invalid segment number after which all segments are not
968- * valid.
969- */
970- if (errorSegNo == 0 ||
971- errorSegNo > thread_args [i ].reader_data .xlogsegno )
972- errorSegNo = thread_args [i ].reader_data .xlogsegno ;
973- continue ;
974- }
975-
976- /* Is this segment valid */
977- if (errorSegNo != 0 &&
978- thread_args [i ].reader_data .xlogsegno > errorSegNo )
979- continue ;
980-
981991cur_rec = & thread_args [i ].reader_data .cur_rec ;
982992/*
983993 * If we got the target return minimum possible record.
@@ -997,9 +1007,16 @@ RunXLogThreads(const char *archivedir, time_t target_time,
9971007 */
9981008else if (last_rec -> rec_lsn < cur_rec -> rec_lsn )
9991009* last_rec = * cur_rec ;
1010+
1011+ /*
1012+ * We reached failed thread, so stop here. We cannot use following
1013+ * WAL records after failed segment.
1014+ */
1015+ if (thread_args [i ].ret != 0 )
1016+ break ;
10001017}
1018+ }
10011019
1002- pfree (threads );
10031020pfree (thread_args );
10041021
10051022return result ;