Skip to content

Commit 0a89f70

Browse files
committed
Issue #32: Wait for LSN in archived dir for PAGE backup
1 parent 24c9541 commit 0a89f70

File tree

2 files changed

+39
-53
lines changed

2 files changed

+39
-53
lines changed

src/backup.c

Lines changed: 34 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,8 @@ static int checkpoint_timeout(void);
104104

105105
//static void backup_list_file(parray *files, const char *root, )
106106
static void parse_backup_filelist_filenames(parray *files, const char *root);
107-
static void wait_wal_lsn(XLogRecPtr lsn, bool wait_prev_segment);
107+
static void wait_wal_lsn(XLogRecPtr lsn, bool is_start_lsn,
108+
bool wait_prev_segment);
108109
static void wait_replica_wal_lsn(XLogRecPtr lsn, bool is_start_backup);
109110
static void make_pagemap_from_ptrack(parray *files);
110111
static void *StreamLog(void *arg);
@@ -1112,20 +1113,17 @@ pg_start_backup(const char *label, bool smooth, pgBackup *backup)
11121113
*/
11131114
pg_switch_wal(conn);
11141115

1115-
if (!stream_wal)
1116-
{
1117-
/*
1118-
* Do not wait start_lsn for stream backup.
1119-
* Because WAL streaming will start after pg_start_backup() in stream
1120-
* mode.
1121-
*/
1116+
if (current.backup_mode == BACKUP_MODE_DIFF_PAGE)
11221117
/* In PAGE mode wait for current segment... */
1123-
if (current.backup_mode == BACKUP_MODE_DIFF_PAGE)
1124-
wait_wal_lsn(backup->start_lsn, false);
1118+
wait_wal_lsn(backup->start_lsn, true, false);
1119+
/*
1120+
* Do not wait start_lsn for stream backup.
1121+
* Because WAL streaming will start after pg_start_backup() in stream
1122+
* mode.
1123+
*/
1124+
else if (!stream_wal)
11251125
/* ...for others wait for previous segment */
1126-
else
1127-
wait_wal_lsn(backup->start_lsn, true);
1128-
}
1126+
wait_wal_lsn(backup->start_lsn, true, true);
11291127

11301128
/* Wait for start_lsn to be replayed by replica */
11311129
if (backup->from_replica)
@@ -1443,16 +1441,20 @@ pg_ptrack_get_and_clear(Oid tablespace_oid, Oid db_oid, Oid rel_filenode,
14431441
* If current backup started in stream mode wait for 'lsn' to be streamed in
14441442
* 'pg_wal' directory.
14451443
*
1444+
* If 'is_start_lsn' is true and backup mode is PAGE then we wait for 'lsn' to
1445+
* be archived in archive 'wal' directory regardless stream mode.
1446+
*
14461447
* If 'wait_prev_segment' wait for previous segment.
14471448
*/
14481449
static void
1449-
wait_wal_lsn(XLogRecPtr lsn, bool wait_prev_segment)
1450+
wait_wal_lsn(XLogRecPtr lsn, bool is_start_lsn, bool wait_prev_segment)
14501451
{
14511452
TimeLineID tli;
14521453
XLogSegNo targetSegNo;
1453-
char wal_dir[MAXPGPATH],
1454-
wal_segment_path[MAXPGPATH];
1455-
char wal_segment[MAXFNAMELEN];
1454+
char pg_wal_dir[MAXPGPATH];
1455+
char wal_segment_path[MAXPGPATH],
1456+
*wal_segment_dir,
1457+
wal_segment[MAXFNAMELEN];
14561458
bool file_exists = false;
14571459
uint32 try_count = 0,
14581460
timeout;
@@ -1469,18 +1471,28 @@ wait_wal_lsn(XLogRecPtr lsn, bool wait_prev_segment)
14691471
targetSegNo--;
14701472
XLogFileName(wal_segment, tli, targetSegNo);
14711473

1472-
if (stream_wal)
1474+
/*
1475+
* In pg_start_backup we wait for 'lsn' in 'pg_wal' directory iff it is
1476+
* stream and non-page backup. Page backup needs archived WAL files, so we
1477+
* wait for 'lsn' in archive 'wal' directory for page backups.
1478+
*
1479+
* In pg_stop_backup it depends only on stream_wal.
1480+
*/
1481+
if (stream_wal &&
1482+
(current.backup_mode != BACKUP_MODE_DIFF_PAGE || !is_start_lsn))
14731483
{
1474-
pgBackupGetPath2(&current, wal_dir, lengthof(wal_dir),
1484+
pgBackupGetPath2(&current, pg_wal_dir, lengthof(pg_wal_dir),
14751485
DATABASE_DIR, PG_XLOG_DIR);
1476-
join_path_components(wal_segment_path, wal_dir, wal_segment);
1486+
join_path_components(wal_segment_path, pg_wal_dir, wal_segment);
1487+
wal_segment_dir = pg_wal_dir;
14771488

14781489
timeout = (uint32) checkpoint_timeout();
14791490
timeout = timeout + timeout * 0.1;
14801491
}
14811492
else
14821493
{
14831494
join_path_components(wal_segment_path, arclog_path, wal_segment);
1495+
wal_segment_dir = arclog_path;
14841496
timeout = archive_timeout;
14851497
}
14861498

@@ -1523,8 +1535,7 @@ wait_wal_lsn(XLogRecPtr lsn, bool wait_prev_segment)
15231535
/*
15241536
* A WAL segment found. Check LSN on it.
15251537
*/
1526-
if ((stream_wal && wal_contains_lsn(wal_dir, lsn, tli)) ||
1527-
(!stream_wal && wal_contains_lsn(arclog_path, lsn, tli)))
1538+
if (wal_contains_lsn(wal_segment_dir, lsn, tli))
15281539
/* Target LSN was found */
15291540
{
15301541
elog(LOG, "Found LSN: %X/%X", (uint32) (lsn >> 32), (uint32) lsn);
@@ -1912,7 +1923,7 @@ pg_stop_backup(pgBackup *backup)
19121923
* Wait for stop_lsn to be archived or streamed.
19131924
* We wait for stop_lsn in stream mode just in case.
19141925
*/
1915-
wait_wal_lsn(stop_backup_lsn, false);
1926+
wait_wal_lsn(stop_backup_lsn, false, false);
19161927

19171928
if (stream_wal)
19181929
{

src/parsexlog.c

Lines changed: 5 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -170,15 +170,16 @@ switchToNextWal(XLogReaderState *xlogreader, xlog_thread_arg *arg)
170170
*/
171171
if (XLogRecPtrIsInvalid(found))
172172
{
173-
elog(WARNING, "could not read WAL record at %X/%X",
174-
(uint32) (arg->startpoint >> 32), (uint32) (arg->startpoint));
173+
elog(WARNING, "Thread [%d]: could not read WAL record at %X/%X",
174+
private_data->thread_num,
175+
(uint32) (arg->startpoint >> 32), (uint32) (arg->startpoint));
175176
PrintXLogCorruptionMsg(private_data, ERROR);
176177
}
177178
arg->startpoint = found;
178179

179180
elog(VERBOSE, "Thread [%d]: switched to LSN %X/%X",
180-
private_data->thread_num,
181-
(uint32) (arg->startpoint >> 32), (uint32) (arg->startpoint));
181+
private_data->thread_num,
182+
(uint32) (arg->startpoint >> 32), (uint32) (arg->startpoint));
182183

183184
return true;
184185
}
@@ -261,32 +262,6 @@ doExtractPageMap(void *arg)
261262
continue;
262263
else
263264
break;
264-
265-
/* Adjust next record position */
266-
XLogSegNoOffsetToRecPtr(private_data->xlogsegno, 0,
267-
extract_arg->startpoint);
268-
/* Skip over the page header */
269-
found = XLogFindNextRecord(xlogreader, extract_arg->startpoint);
270-
/*
271-
* We get invalid WAL record pointer usually when WAL segment is
272-
* absent or is corrupted.
273-
*/
274-
if (XLogRecPtrIsInvalid(found))
275-
{
276-
elog(WARNING, "Thread [%d]: could not read WAL record at %X/%X",
277-
private_data->thread_num,
278-
(uint32) (extract_arg->startpoint >> 32),
279-
(uint32) (extract_arg->startpoint));
280-
PrintXLogCorruptionMsg(private_data, ERROR);
281-
}
282-
extract_arg->startpoint = found;
283-
284-
elog(VERBOSE, "Thread [%d]: switched to LSN %X/%X",
285-
private_data->thread_num,
286-
(uint32) (extract_arg->startpoint >> 32),
287-
(uint32) (extract_arg->startpoint));
288-
289-
continue;
290265
}
291266

292267
errptr = extract_arg->startpoint ?

0 commit comments

Comments
 (0)