Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit ebeebca

Browse files
committed
Get last valid WAL record correctly using sorted thread_args array
1 parent aa1812e commit ebeebca

File tree

1 file changed

+36
-19
lines changed

1 file changed

+36
-19
lines changed

src/parsexlog.c

+36-19
Original file line numberDiff line numberDiff line change
@@ -860,6 +860,18 @@ InitXLogPageRead(XLogReaderData *reader_data, const char *archivedir,
860860
return 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,
877889
int i;
878890
int threads_need = 0;
879891
XLogSegNo endSegNo = 0;
880-
XLogSegNo errorSegNo = 0;
881892
bool result = true;
882893

883894
if (!XRecOffIsValid(startpoint))
@@ -956,28 +967,27 @@ RunXLogThreads(const char *archivedir, time_t target_time,
956967
result = false;
957968
}
958969

970+
/* Release threads here, use thread_args only below */
971+
pfree(threads);
972+
threads = NULL;
973+
959974
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+
960987
for (i = 0; i < threads_need; i++)
961988
{
962989
XLogRecTarget *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-
981991
cur_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
*/
9981008
else 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);
10031020
pfree(thread_args);
10041021

10051022
return result;

0 commit comments

Comments
 (0)