1
0
mirror of https://github.com/postgrespro/pg_probackup.git synced 2025-07-17 07:22:20 +02:00

Issue #32: Wait for LSN in archived dir for PAGE backup

This commit is contained in:
Arthur Zakirov
2018-09-04 14:08:50 +03:00
parent 24c95417a5
commit 0a89f702e3
2 changed files with 39 additions and 53 deletions

View File

@ -104,7 +104,8 @@ static int checkpoint_timeout(void);
//static void backup_list_file(parray *files, const char *root, ) //static void backup_list_file(parray *files, const char *root, )
static void parse_backup_filelist_filenames(parray *files, const char *root); static void parse_backup_filelist_filenames(parray *files, const char *root);
static void wait_wal_lsn(XLogRecPtr lsn, bool wait_prev_segment); static void wait_wal_lsn(XLogRecPtr lsn, bool is_start_lsn,
bool wait_prev_segment);
static void wait_replica_wal_lsn(XLogRecPtr lsn, bool is_start_backup); static void wait_replica_wal_lsn(XLogRecPtr lsn, bool is_start_backup);
static void make_pagemap_from_ptrack(parray *files); static void make_pagemap_from_ptrack(parray *files);
static void *StreamLog(void *arg); static void *StreamLog(void *arg);
@ -1112,20 +1113,17 @@ pg_start_backup(const char *label, bool smooth, pgBackup *backup)
*/ */
pg_switch_wal(conn); pg_switch_wal(conn);
if (!stream_wal) if (current.backup_mode == BACKUP_MODE_DIFF_PAGE)
{
/*
* Do not wait start_lsn for stream backup.
* Because WAL streaming will start after pg_start_backup() in stream
* mode.
*/
/* In PAGE mode wait for current segment... */ /* In PAGE mode wait for current segment... */
if (current.backup_mode == BACKUP_MODE_DIFF_PAGE) wait_wal_lsn(backup->start_lsn, true, false);
wait_wal_lsn(backup->start_lsn, false); /*
* Do not wait start_lsn for stream backup.
* Because WAL streaming will start after pg_start_backup() in stream
* mode.
*/
else if (!stream_wal)
/* ...for others wait for previous segment */ /* ...for others wait for previous segment */
else wait_wal_lsn(backup->start_lsn, true, true);
wait_wal_lsn(backup->start_lsn, true);
}
/* Wait for start_lsn to be replayed by replica */ /* Wait for start_lsn to be replayed by replica */
if (backup->from_replica) if (backup->from_replica)
@ -1443,16 +1441,20 @@ pg_ptrack_get_and_clear(Oid tablespace_oid, Oid db_oid, Oid rel_filenode,
* If current backup started in stream mode wait for 'lsn' to be streamed in * If current backup started in stream mode wait for 'lsn' to be streamed in
* 'pg_wal' directory. * 'pg_wal' directory.
* *
* If 'is_start_lsn' is true and backup mode is PAGE then we wait for 'lsn' to
* be archived in archive 'wal' directory regardless stream mode.
*
* If 'wait_prev_segment' wait for previous segment. * If 'wait_prev_segment' wait for previous segment.
*/ */
static void static void
wait_wal_lsn(XLogRecPtr lsn, bool wait_prev_segment) wait_wal_lsn(XLogRecPtr lsn, bool is_start_lsn, bool wait_prev_segment)
{ {
TimeLineID tli; TimeLineID tli;
XLogSegNo targetSegNo; XLogSegNo targetSegNo;
char wal_dir[MAXPGPATH], char pg_wal_dir[MAXPGPATH];
wal_segment_path[MAXPGPATH]; char wal_segment_path[MAXPGPATH],
char wal_segment[MAXFNAMELEN]; *wal_segment_dir,
wal_segment[MAXFNAMELEN];
bool file_exists = false; bool file_exists = false;
uint32 try_count = 0, uint32 try_count = 0,
timeout; timeout;
@ -1469,11 +1471,20 @@ wait_wal_lsn(XLogRecPtr lsn, bool wait_prev_segment)
targetSegNo--; targetSegNo--;
XLogFileName(wal_segment, tli, targetSegNo); XLogFileName(wal_segment, tli, targetSegNo);
if (stream_wal) /*
* In pg_start_backup we wait for 'lsn' in 'pg_wal' directory iff it is
* stream and non-page backup. Page backup needs archived WAL files, so we
* wait for 'lsn' in archive 'wal' directory for page backups.
*
* In pg_stop_backup it depends only on stream_wal.
*/
if (stream_wal &&
(current.backup_mode != BACKUP_MODE_DIFF_PAGE || !is_start_lsn))
{ {
pgBackupGetPath2(&current, wal_dir, lengthof(wal_dir), pgBackupGetPath2(&current, pg_wal_dir, lengthof(pg_wal_dir),
DATABASE_DIR, PG_XLOG_DIR); DATABASE_DIR, PG_XLOG_DIR);
join_path_components(wal_segment_path, wal_dir, wal_segment); join_path_components(wal_segment_path, pg_wal_dir, wal_segment);
wal_segment_dir = pg_wal_dir;
timeout = (uint32) checkpoint_timeout(); timeout = (uint32) checkpoint_timeout();
timeout = timeout + timeout * 0.1; timeout = timeout + timeout * 0.1;
@ -1481,6 +1492,7 @@ wait_wal_lsn(XLogRecPtr lsn, bool wait_prev_segment)
else else
{ {
join_path_components(wal_segment_path, arclog_path, wal_segment); join_path_components(wal_segment_path, arclog_path, wal_segment);
wal_segment_dir = arclog_path;
timeout = archive_timeout; timeout = archive_timeout;
} }
@ -1523,8 +1535,7 @@ wait_wal_lsn(XLogRecPtr lsn, bool wait_prev_segment)
/* /*
* A WAL segment found. Check LSN on it. * A WAL segment found. Check LSN on it.
*/ */
if ((stream_wal && wal_contains_lsn(wal_dir, lsn, tli)) || if (wal_contains_lsn(wal_segment_dir, lsn, tli))
(!stream_wal && wal_contains_lsn(arclog_path, lsn, tli)))
/* Target LSN was found */ /* Target LSN was found */
{ {
elog(LOG, "Found LSN: %X/%X", (uint32) (lsn >> 32), (uint32) lsn); elog(LOG, "Found LSN: %X/%X", (uint32) (lsn >> 32), (uint32) lsn);
@ -1912,7 +1923,7 @@ pg_stop_backup(pgBackup *backup)
* Wait for stop_lsn to be archived or streamed. * Wait for stop_lsn to be archived or streamed.
* We wait for stop_lsn in stream mode just in case. * We wait for stop_lsn in stream mode just in case.
*/ */
wait_wal_lsn(stop_backup_lsn, false); wait_wal_lsn(stop_backup_lsn, false, false);
if (stream_wal) if (stream_wal)
{ {

View File

@ -170,15 +170,16 @@ switchToNextWal(XLogReaderState *xlogreader, xlog_thread_arg *arg)
*/ */
if (XLogRecPtrIsInvalid(found)) if (XLogRecPtrIsInvalid(found))
{ {
elog(WARNING, "could not read WAL record at %X/%X", elog(WARNING, "Thread [%d]: could not read WAL record at %X/%X",
(uint32) (arg->startpoint >> 32), (uint32) (arg->startpoint)); private_data->thread_num,
(uint32) (arg->startpoint >> 32), (uint32) (arg->startpoint));
PrintXLogCorruptionMsg(private_data, ERROR); PrintXLogCorruptionMsg(private_data, ERROR);
} }
arg->startpoint = found; arg->startpoint = found;
elog(VERBOSE, "Thread [%d]: switched to LSN %X/%X", elog(VERBOSE, "Thread [%d]: switched to LSN %X/%X",
private_data->thread_num, private_data->thread_num,
(uint32) (arg->startpoint >> 32), (uint32) (arg->startpoint)); (uint32) (arg->startpoint >> 32), (uint32) (arg->startpoint));
return true; return true;
} }
@ -261,32 +262,6 @@ doExtractPageMap(void *arg)
continue; continue;
else else
break; break;
/* Adjust next record position */
XLogSegNoOffsetToRecPtr(private_data->xlogsegno, 0,
extract_arg->startpoint);
/* Skip over the page header */
found = XLogFindNextRecord(xlogreader, extract_arg->startpoint);
/*
* We get invalid WAL record pointer usually when WAL segment is
* absent or is corrupted.
*/
if (XLogRecPtrIsInvalid(found))
{
elog(WARNING, "Thread [%d]: could not read WAL record at %X/%X",
private_data->thread_num,
(uint32) (extract_arg->startpoint >> 32),
(uint32) (extract_arg->startpoint));
PrintXLogCorruptionMsg(private_data, ERROR);
}
extract_arg->startpoint = found;
elog(VERBOSE, "Thread [%d]: switched to LSN %X/%X",
private_data->thread_num,
(uint32) (extract_arg->startpoint >> 32),
(uint32) (extract_arg->startpoint));
continue;
} }
errptr = extract_arg->startpoint ? errptr = extract_arg->startpoint ?