1
0
mirror of https://github.com/postgrespro/pg_probackup.git synced 2025-02-02 13:36:08 +02:00

Check target LSN. Archived WAL segment should contain it.

This commit is contained in:
Arthur Zakirov 2017-04-20 12:38:51 +03:00
parent eaccb463df
commit 1c87d613f4
4 changed files with 73 additions and 7 deletions

View File

@ -239,7 +239,7 @@ do_backup_database(parray *backup_list)
if (ptrack_lsn > prev_backup->stop_lsn)
{
elog(ERROR, "lsn from ptrack_control %lx differs from lsn of previous ptrack backup %lx.\n"
elog(ERROR, "LSN from ptrack_control %lx differs from LSN of previous ptrack backup %lx.\n"
"Create new full backup before an incremental one.",
ptrack_lsn, prev_backup->start_lsn);
}
@ -714,7 +714,8 @@ pg_ptrack_get_and_clear(Oid tablespace_oid, Oid db_oid, Oid rel_oid,
}
/*
* TODO Add comment
* Wait for target 'lsn' to be archived in archive 'wal' directory with
* WAL segment file.
*/
static void
wait_archive_lsn(XLogRecPtr lsn, bool prev_segno)
@ -729,7 +730,7 @@ wait_archive_lsn(XLogRecPtr lsn, bool prev_segno)
tli = get_current_timeline(false);
/* Compute the name of the WAL file containig requested lsn */
/* Compute the name of the WAL file containig requested LSN */
XLByteToSeg(lsn, targetSegNo);
if (prev_segno)
targetSegNo--;
@ -747,7 +748,7 @@ wait_archive_lsn(XLogRecPtr lsn, bool prev_segno)
/* Inform user if WAL segment is absent in first attempt */
if (try_count == 1)
elog(INFO, "wait for lsn %X/%X in archived WAL segment %s",
elog(INFO, "wait for LSN %X/%X in archived WAL segment %s",
(uint32) (lsn >> 32), (uint32) lsn, wal_path);
if (archive_timeout > 0 && try_count > archive_timeout)
@ -755,6 +756,14 @@ wait_archive_lsn(XLogRecPtr lsn, bool prev_segno)
"switched WAL segment %s could not be archived in %d seconds",
wal_file, archive_timeout);
}
/*
* WAL segment was archived. Check LSN on it if we waited current WAL
* segment, not previous.
*/
if (!prev_segno && !wal_contains_lsn(arclog_path, lsn, tli))
elog(ERROR, "WAL segment %s doesn't contain target LSN %X/%X",
wal_file, (uint32) (lsn >> 32), (uint32) lsn);
}
/*

View File

@ -303,6 +303,7 @@ read_recovery_info(const char *archivedir, TimeLineID tli,
XLogRecPtr startpoint = stop_lsn;
XLogReaderState *xlogreader;
XLogPageReadPrivate private;
bool res;
private.archivedir = archivedir;
private.tli = tli;
@ -342,12 +343,66 @@ read_recovery_info(const char *archivedir, TimeLineID tli,
*recovery_time = timestamptz_to_time_t(last_time);
*recovery_xid = XLogRecGetXid(xlogreader);
return true;
/* Found timestamp in WAL record 'record' */
res = true;
goto cleanup;
}
} while (startpoint >= start_lsn);
/* Didn't find timestamp from WAL records between start_lsn and stop_lsn */
return false;
res = false;
cleanup:
XLogReaderFree(xlogreader);
if (xlogreadfd != -1)
{
close(xlogreadfd);
xlogreadfd = -1;
xlogexists = false;
}
return res;
}
/*
* Check if WAL segment file 'wal_path' contains 'target_lsn'.
*/
bool
wal_contains_lsn(const char *archivedir, XLogRecPtr target_lsn,
TimeLineID target_tli)
{
XLogReaderState *xlogreader;
XLogPageReadPrivate private;
char *errormsg;
bool res;
private.archivedir = archivedir;
private.tli = target_tli;
xlogreader = XLogReaderAllocate(&SimpleXLogPageRead, &private);
if (xlogreader == NULL)
elog(ERROR, "out of memory");
res = XLogReadRecord(xlogreader, target_lsn, &errormsg) != NULL;
if (!res)
{
if (errormsg)
elog(ERROR, "could not read WAL record at %X/%X: %s",
(uint32) (target_lsn >> 32), (uint32) (target_lsn),
errormsg);
/* Didn't find 'target_lsn' and there is no error, return false */
}
XLogReaderFree(xlogreader);
if (xlogreadfd != -1)
{
close(xlogreadfd);
xlogreadfd = -1;
xlogexists = false;
}
return res;
}
/* XLogreader callback function, to read a WAL page */

View File

@ -368,6 +368,8 @@ extern bool read_recovery_info(const char *archivedir, TimeLineID tli,
XLogRecPtr start_lsn, XLogRecPtr stop_lsn,
time_t *recovery_time,
TransactionId *recovery_xid);
extern bool wal_contains_lsn(const char *archivedir, XLogRecPtr target_lsn,
TimeLineID target_tli);
/* in util.c */
extern TimeLineID get_current_timeline(bool safe);

View File

@ -790,7 +790,7 @@ readTimeLineHistory_probackup(TimeLineID targetTLI)
/* append target timeline */
entry = pgut_new(TimeLineHistoryEntry);
entry->tli = targetTLI;
/* lsn in target timeline is valid */
/* LSN in target timeline is valid */
entry->end = (uint32) (-1UL << 32) | -1UL;
parray_insert(result, 0, entry);