Skip to content

Commit 3a7b6d5

Browse files
author
Artur Zakirov
committed
Wait right WAL segment for backup from replica
1 parent 515150c commit 3a7b6d5

File tree

3 files changed

+32
-19
lines changed

3 files changed

+32
-19
lines changed

backup.c

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ static void pg_switch_xlog(void);
7272
static bool pg_is_standby(void);
7373
static void add_pgdata_files(parray *files, const char *root);
7474
static void create_file_list(parray *files, const char *root, bool is_append);
75-
static void wait_archive_lsn(XLogRecPtr lsn, bool last_segno);
75+
static void wait_archive_lsn(XLogRecPtr lsn, bool prev_segno);
7676
static void make_pagemap_from_ptrack(parray *files);
7777
static void StreamLog(void *arg);
7878

@@ -230,17 +230,9 @@ do_backup_database(parray *backup_list, bool smooth_checkpoint)
230230
* Build page mapping in differential mode. When using this mode, the
231231
* list of blocks to be taken is known by scanning the WAL segments
232232
* present in archives up to the point where start backup has begun.
233-
* However, normally this segment is not yet available in the archives,
234-
* leading to failures when building the page map. Hence before doing
235-
* anything and in order to ensure that all the segments needed for the
236-
* scan are here, for a switch of the last segment with pg_switch_xlog.
237233
*/
238234
if (current.backup_mode == BACKUP_MODE_DIFF_PAGE)
239235
{
240-
/* Enforce archiving of last segment and wait for it to be here */
241-
if (!from_replica)
242-
pg_switch_xlog();
243-
244236
/* Now build the page map */
245237
parray_qsort(backup_files_list, pgFileComparePathDesc);
246238
elog(LOG, "extractPageMap");
@@ -252,7 +244,12 @@ do_backup_database(parray *backup_list, bool smooth_checkpoint)
252244
(uint32) (current.start_lsn >> 32),
253245
(uint32) (current.start_lsn));
254246
extractPageMap(arclog_path, prev_backup->start_lsn, current.tli,
255-
current.start_lsn);
247+
current.start_lsn,
248+
/*
249+
* For backup from master wait for previous segment.
250+
* For backup from replica wait for current segment.
251+
*/
252+
!from_replica);
256253
}
257254
else if (current.backup_mode == BACKUP_MODE_DIFF_PTRACK)
258255
{
@@ -602,7 +599,12 @@ pg_start_backup(const char *label, bool smooth, pgBackup *backup)
602599
backup->start_lsn = (XLogRecPtr) ((uint64) xlogid << 32) | xrecoff;
603600

604601
if (!stream_wal)
605-
wait_archive_lsn(backup->start_lsn, true);
602+
wait_archive_lsn(backup->start_lsn,
603+
/*
604+
* For backup from master wait for previous segment.
605+
* For backup from replica wait for current segment.
606+
*/
607+
!from_replica);
606608

607609
PQclear(res);
608610
}
@@ -729,7 +731,7 @@ pg_ptrack_get_and_clear(Oid tablespace_oid, Oid db_oid, Oid rel_oid,
729731
}
730732

731733
static void
732-
wait_archive_lsn(XLogRecPtr lsn, bool last_segno)
734+
wait_archive_lsn(XLogRecPtr lsn, bool prev_segno)
733735
{
734736
TimeLineID tli;
735737
XLogSegNo targetSegNo;
@@ -741,7 +743,7 @@ wait_archive_lsn(XLogRecPtr lsn, bool last_segno)
741743

742744
/* As well as WAL file name */
743745
XLByteToSeg(lsn, targetSegNo);
744-
if (last_segno)
746+
if (prev_segno)
745747
targetSegNo--;
746748
XLogFileName(wal_file, tli, targetSegNo);
747749

@@ -844,6 +846,9 @@ pg_stop_backup(pgBackup *backup)
844846

845847
PQclear(res);
846848

849+
if (!stream_wal)
850+
wait_archive_lsn(stop_backup_lsn, false);
851+
847852
/* Fill in fields if backup exists */
848853
if (backup != NULL)
849854
{
@@ -868,9 +873,6 @@ pg_stop_backup(pgBackup *backup)
868873

869874
PQclear(res);
870875
}
871-
872-
if (!stream_wal)
873-
wait_archive_lsn(stop_backup_lsn, false);
874876
}
875877

876878
/*

parsexlog.c

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,22 +54,31 @@ static int SimpleXLogPageRead(XLogReaderState *xlogreader,
5454
* Read WAL from the archive directory, starting from 'startpoint' on the
5555
* given timeline, until 'endpoint'. Make note of the data blocks touched
5656
* by the WAL records, and return them in a page map.
57+
*
58+
* If **prev_segno** is true then read all segments up to **endpoint** segment
59+
* minus one. Else read all segments up to **endpoint** segment.
5760
*/
5861
void
5962
extractPageMap(const char *archivedir, XLogRecPtr startpoint, TimeLineID tli,
60-
XLogRecPtr endpoint)
63+
XLogRecPtr endpoint, bool prev_segno)
6164
{
6265
XLogRecord *record;
6366
XLogReaderState *xlogreader;
6467
char *errormsg;
6568
XLogPageReadPrivate private;
69+
XLogSegNo endSegNo,
70+
nextSegNo = 0;
6671

6772
private.archivedir = archivedir;
6873
private.tli = tli;
6974
xlogreader = XLogReaderAllocate(&SimpleXLogPageRead, &private);
7075
if (xlogreader == NULL)
7176
elog(ERROR, "out of memory");
7277

78+
XLByteToSeg(endpoint, endSegNo);
79+
if (prev_segno)
80+
endSegNo--;
81+
7382
do
7483
{
7584
record = XLogReadRecord(xlogreader, startpoint, &errormsg);
@@ -93,7 +102,9 @@ extractPageMap(const char *archivedir, XLogRecPtr startpoint, TimeLineID tli,
93102

94103
startpoint = InvalidXLogRecPtr; /* continue reading at next record */
95104

96-
} while (xlogreader->ReadRecPtr != endpoint);
105+
XLByteToSeg(xlogreader->EndRecPtr, nextSegNo);
106+
107+
} while (nextSegNo <= endSegNo && xlogreader->EndRecPtr != endpoint);
97108

98109
XLogReaderFree(xlogreader);
99110
if (xlogreadfd != -1)

pg_probackup.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -351,7 +351,7 @@ extern bool calc_file(pgFile *file);
351351
extern void extractPageMap(const char *datadir,
352352
XLogRecPtr startpoint,
353353
TimeLineID tli,
354-
XLogRecPtr endpoint);
354+
XLogRecPtr endpoint, bool prev_segno);
355355
extern void validate_wal(pgBackup *backup,
356356
const char *archivedir,
357357
time_t target_time,

0 commit comments

Comments
 (0)