mirror of
https://github.com/postgrespro/pg_probackup.git
synced 2025-02-03 14:01:57 +02:00
Check target LSN. Archived WAL segment should contain it.
This commit is contained in:
parent
eaccb463df
commit
1c87d613f4
17
backup.c
17
backup.c
@ -239,7 +239,7 @@ do_backup_database(parray *backup_list)
|
|||||||
|
|
||||||
if (ptrack_lsn > prev_backup->stop_lsn)
|
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.",
|
"Create new full backup before an incremental one.",
|
||||||
ptrack_lsn, prev_backup->start_lsn);
|
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
|
static void
|
||||||
wait_archive_lsn(XLogRecPtr lsn, bool prev_segno)
|
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);
|
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);
|
XLByteToSeg(lsn, targetSegNo);
|
||||||
if (prev_segno)
|
if (prev_segno)
|
||||||
targetSegNo--;
|
targetSegNo--;
|
||||||
@ -747,7 +748,7 @@ wait_archive_lsn(XLogRecPtr lsn, bool prev_segno)
|
|||||||
|
|
||||||
/* Inform user if WAL segment is absent in first attempt */
|
/* Inform user if WAL segment is absent in first attempt */
|
||||||
if (try_count == 1)
|
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);
|
(uint32) (lsn >> 32), (uint32) lsn, wal_path);
|
||||||
|
|
||||||
if (archive_timeout > 0 && try_count > archive_timeout)
|
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",
|
"switched WAL segment %s could not be archived in %d seconds",
|
||||||
wal_file, archive_timeout);
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
59
parsexlog.c
59
parsexlog.c
@ -303,6 +303,7 @@ read_recovery_info(const char *archivedir, TimeLineID tli,
|
|||||||
XLogRecPtr startpoint = stop_lsn;
|
XLogRecPtr startpoint = stop_lsn;
|
||||||
XLogReaderState *xlogreader;
|
XLogReaderState *xlogreader;
|
||||||
XLogPageReadPrivate private;
|
XLogPageReadPrivate private;
|
||||||
|
bool res;
|
||||||
|
|
||||||
private.archivedir = archivedir;
|
private.archivedir = archivedir;
|
||||||
private.tli = tli;
|
private.tli = tli;
|
||||||
@ -342,12 +343,66 @@ read_recovery_info(const char *archivedir, TimeLineID tli,
|
|||||||
*recovery_time = timestamptz_to_time_t(last_time);
|
*recovery_time = timestamptz_to_time_t(last_time);
|
||||||
*recovery_xid = XLogRecGetXid(xlogreader);
|
*recovery_xid = XLogRecGetXid(xlogreader);
|
||||||
|
|
||||||
return true;
|
/* Found timestamp in WAL record 'record' */
|
||||||
|
res = true;
|
||||||
|
goto cleanup;
|
||||||
}
|
}
|
||||||
} while (startpoint >= start_lsn);
|
} while (startpoint >= start_lsn);
|
||||||
|
|
||||||
/* Didn't find timestamp from WAL records between start_lsn and stop_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 */
|
/* XLogreader callback function, to read a WAL page */
|
||||||
|
@ -368,6 +368,8 @@ extern bool read_recovery_info(const char *archivedir, TimeLineID tli,
|
|||||||
XLogRecPtr start_lsn, XLogRecPtr stop_lsn,
|
XLogRecPtr start_lsn, XLogRecPtr stop_lsn,
|
||||||
time_t *recovery_time,
|
time_t *recovery_time,
|
||||||
TransactionId *recovery_xid);
|
TransactionId *recovery_xid);
|
||||||
|
extern bool wal_contains_lsn(const char *archivedir, XLogRecPtr target_lsn,
|
||||||
|
TimeLineID target_tli);
|
||||||
|
|
||||||
/* in util.c */
|
/* in util.c */
|
||||||
extern TimeLineID get_current_timeline(bool safe);
|
extern TimeLineID get_current_timeline(bool safe);
|
||||||
|
@ -790,7 +790,7 @@ readTimeLineHistory_probackup(TimeLineID targetTLI)
|
|||||||
/* append target timeline */
|
/* append target timeline */
|
||||||
entry = pgut_new(TimeLineHistoryEntry);
|
entry = pgut_new(TimeLineHistoryEntry);
|
||||||
entry->tli = targetTLI;
|
entry->tli = targetTLI;
|
||||||
/* lsn in target timeline is valid */
|
/* LSN in target timeline is valid */
|
||||||
entry->end = (uint32) (-1UL << 32) | -1UL;
|
entry->end = (uint32) (-1UL << 32) | -1UL;
|
||||||
parray_insert(result, 0, entry);
|
parray_insert(result, 0, entry);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user