@@ -860,6 +860,18 @@ InitXLogPageRead(XLogReaderData *reader_data, const char *archivedir,
860
860
return xlogreader ;
861
861
}
862
862
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
+
863
875
/*
864
876
* Run WAL processing routines using threads. Start from startpoint up to
865
877
* endpoint. It is possible to send zero endpoint, threads will read WAL
@@ -877,7 +889,6 @@ RunXLogThreads(const char *archivedir, time_t target_time,
877
889
int i ;
878
890
int threads_need = 0 ;
879
891
XLogSegNo endSegNo = 0 ;
880
- XLogSegNo errorSegNo = 0 ;
881
892
bool result = true;
882
893
883
894
if (!XRecOffIsValid (startpoint ))
@@ -956,28 +967,27 @@ RunXLogThreads(const char *archivedir, time_t target_time,
956
967
result = false;
957
968
}
958
969
970
+ /* Release threads here, use thread_args only below */
971
+ pfree (threads );
972
+ threads = NULL ;
973
+
959
974
if (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
+
960
987
for (i = 0 ; i < threads_need ; i ++ )
961
988
{
962
989
XLogRecTarget * cur_rec ;
963
990
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
-
981
991
cur_rec = & thread_args [i ].reader_data .cur_rec ;
982
992
/*
983
993
* If we got the target return minimum possible record.
@@ -997,9 +1007,16 @@ RunXLogThreads(const char *archivedir, time_t target_time,
997
1007
*/
998
1008
else if (last_rec -> rec_lsn < cur_rec -> rec_lsn )
999
1009
* 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 ;
1000
1017
}
1018
+ }
1001
1019
1002
- pfree (threads );
1003
1020
pfree (thread_args );
1004
1021
1005
1022
return result ;
0 commit comments