You've already forked pg_probackup
mirror of
https://github.com/postgrespro/pg_probackup.git
synced 2025-07-15 07:04:14 +02:00
if WAL segment required to create pagemap is absent, throw an ERROR
This commit is contained in:
45
parsexlog.c
45
parsexlog.c
@ -123,6 +123,7 @@ extractPageMap(const char *archivedir, XLogRecPtr startpoint, TimeLineID tli,
|
|||||||
do
|
do
|
||||||
{
|
{
|
||||||
record = XLogReadRecord(xlogreader, startpoint, &errormsg);
|
record = XLogReadRecord(xlogreader, startpoint, &errormsg);
|
||||||
|
|
||||||
if (record == NULL)
|
if (record == NULL)
|
||||||
{
|
{
|
||||||
XLogRecPtr errptr;
|
XLogRecPtr errptr;
|
||||||
@ -130,12 +131,23 @@ extractPageMap(const char *archivedir, XLogRecPtr startpoint, TimeLineID tli,
|
|||||||
errptr = startpoint ? startpoint : xlogreader->EndRecPtr;
|
errptr = startpoint ? startpoint : xlogreader->EndRecPtr;
|
||||||
|
|
||||||
if (errormsg)
|
if (errormsg)
|
||||||
elog(ERROR, "could not read WAL record at %X/%X: %s",
|
elog(WARNING, "could not read WAL record at %X/%X: %s",
|
||||||
(uint32) (errptr >> 32), (uint32) (errptr),
|
(uint32) (errptr >> 32), (uint32) (errptr),
|
||||||
errormsg);
|
errormsg);
|
||||||
else
|
else
|
||||||
elog(ERROR, "could not read WAL record at %X/%X",
|
elog(WARNING, "could not read WAL record at %X/%X",
|
||||||
(uint32) (errptr >> 32), (uint32) (errptr));
|
(uint32) (errptr >> 32), (uint32) (errptr));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If we don't have all WAL files from prev backup start_lsn to current
|
||||||
|
* start_lsn, we won't be able to build page map and PAGE backup will
|
||||||
|
* be incorrect. Stop it and throw an error.
|
||||||
|
*/
|
||||||
|
if (!xlogexists)
|
||||||
|
elog(ERROR, "WAL segment \"%s\" is absent", xlogfpath);
|
||||||
|
else if (xlogreadfd != -1)
|
||||||
|
elog(ERROR, "Possible WAL CORRUPTION."
|
||||||
|
"Error has occured during reading WAL segment \"%s\"", xlogfpath);
|
||||||
}
|
}
|
||||||
|
|
||||||
extractPageInfo(xlogreader);
|
extractPageInfo(xlogreader);
|
||||||
@ -143,7 +155,6 @@ extractPageMap(const char *archivedir, XLogRecPtr startpoint, TimeLineID tli,
|
|||||||
startpoint = InvalidXLogRecPtr; /* continue reading at next record */
|
startpoint = InvalidXLogRecPtr; /* continue reading at next record */
|
||||||
|
|
||||||
XLByteToSeg(xlogreader->EndRecPtr, nextSegNo);
|
XLByteToSeg(xlogreader->EndRecPtr, nextSegNo);
|
||||||
|
|
||||||
} while (nextSegNo <= endSegNo && xlogreader->EndRecPtr != endpoint);
|
} while (nextSegNo <= endSegNo && xlogreader->EndRecPtr != endpoint);
|
||||||
|
|
||||||
XLogReaderFree(xlogreader);
|
XLogReaderFree(xlogreader);
|
||||||
@ -228,6 +239,8 @@ validate_wal(pgBackup *backup,
|
|||||||
startpoint = InvalidXLogRecPtr; /* continue reading at next record */
|
startpoint = InvalidXLogRecPtr; /* continue reading at next record */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* TODO Add comment */
|
||||||
if (last_time > 0)
|
if (last_time > 0)
|
||||||
time2iso(last_timestamp, lengthof(last_timestamp),
|
time2iso(last_timestamp, lengthof(last_timestamp),
|
||||||
timestamptz_to_time_t(last_time));
|
timestamptz_to_time_t(last_time));
|
||||||
@ -237,33 +250,37 @@ validate_wal(pgBackup *backup,
|
|||||||
if (last_xid == InvalidTransactionId)
|
if (last_xid == InvalidTransactionId)
|
||||||
last_xid = backup->recovery_xid;
|
last_xid = backup->recovery_xid;
|
||||||
|
|
||||||
/* There are all need WAL records */
|
/* There are all needed WAL records */
|
||||||
if (all_wal)
|
if (all_wal)
|
||||||
elog(INFO, "backup validation completed successfully on time %s and xid " XID_FMT,
|
elog(INFO, "backup validation completed successfully on time %s and xid " XID_FMT,
|
||||||
last_timestamp, last_xid);
|
last_timestamp, last_xid);
|
||||||
/* There are not need WAL records */
|
/* Some needed WAL records are absent */
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (xlogfpath[0] != 0)
|
if (xlogfpath[0] != 0)
|
||||||
{
|
{
|
||||||
/* Update backup status */
|
/* XLOG reader couldn't read WAL segment.
|
||||||
backup->status = BACKUP_STATUS_CORRUPT;
|
* We throw a WARNING here to be able to update backup status below.
|
||||||
pgBackupWriteBackupControlFile(backup);
|
*/
|
||||||
|
|
||||||
/* XLOG reader couldnt read WAL segment */
|
|
||||||
if (!xlogexists)
|
if (!xlogexists)
|
||||||
|
{
|
||||||
elog(WARNING, "WAL segment \"%s\" is absent", xlogfpath);
|
elog(WARNING, "WAL segment \"%s\" is absent", xlogfpath);
|
||||||
|
}
|
||||||
else if (xlogreadfd != -1)
|
else if (xlogreadfd != -1)
|
||||||
elog(ERROR, "Possible WAL CORRUPTION."
|
{
|
||||||
"Error has occured during reading WAL segment \"%s\"", xlogfpath);
|
elog(WARNING, "Possible WAL CORRUPTION."
|
||||||
|
"Error has occured during reading WAL segment \"%s\"", xlogfpath);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!got_endpoint)
|
if (!got_endpoint)
|
||||||
{
|
{
|
||||||
/* Update backup status */
|
/*
|
||||||
|
* If we don't have WAL between start_lsn and stop_lsn,
|
||||||
|
* the backup is definitely corrupted. Update its status.
|
||||||
|
*/
|
||||||
backup->status = BACKUP_STATUS_CORRUPT;
|
backup->status = BACKUP_STATUS_CORRUPT;
|
||||||
pgBackupWriteBackupControlFile(backup);
|
pgBackupWriteBackupControlFile(backup);
|
||||||
|
|
||||||
elog(ERROR, "there are not enough WAL records to restore from %X/%X to %X/%X",
|
elog(ERROR, "there are not enough WAL records to restore from %X/%X to %X/%X",
|
||||||
(uint32) (backup->start_lsn >> 32),
|
(uint32) (backup->start_lsn >> 32),
|
||||||
(uint32) (backup->start_lsn),
|
(uint32) (backup->start_lsn),
|
||||||
|
@ -17,8 +17,8 @@ class ValidateTest(ProbackupTest, unittest.TestCase):
|
|||||||
def tearDownClass(cls):
|
def tearDownClass(cls):
|
||||||
stop_all()
|
stop_all()
|
||||||
|
|
||||||
# @unittest.skip("skip")
|
#@unittest.skip("skip")
|
||||||
# @unittest.expectedFailure
|
#@unittest.expectedFailure
|
||||||
def test_validate_wal_unreal_values(self):
|
def test_validate_wal_unreal_values(self):
|
||||||
"""recovery to latest from full backup"""
|
"""recovery to latest from full backup"""
|
||||||
fname = self.id().split('.')[3]
|
fname = self.id().split('.')[3]
|
||||||
@ -177,6 +177,7 @@ class ValidateTest(ProbackupTest, unittest.TestCase):
|
|||||||
self.assertEqual('CORRUPT', self.show_pb(node, id=backup_id)['status'], 'Backup STATUS should be "CORRUPT"')
|
self.assertEqual('CORRUPT', self.show_pb(node, id=backup_id)['status'], 'Backup STATUS should be "CORRUPT"')
|
||||||
node.stop()
|
node.stop()
|
||||||
|
|
||||||
|
@unittest.skip("skip")
|
||||||
def test_validate_wal_lost_segment_1(self):
|
def test_validate_wal_lost_segment_1(self):
|
||||||
"""Loose segment which belong to some backup"""
|
"""Loose segment which belong to some backup"""
|
||||||
fname = self.id().split('.')[3]
|
fname = self.id().split('.')[3]
|
||||||
@ -245,5 +246,5 @@ class ValidateTest(ProbackupTest, unittest.TestCase):
|
|||||||
self.backup_pb(node, backup_type='page')
|
self.backup_pb(node, backup_type='page')
|
||||||
self.assertEqual(1, 0, "Expecting Error in PAGE backup because of wal segment disappearance")
|
self.assertEqual(1, 0, "Expecting Error in PAGE backup because of wal segment disappearance")
|
||||||
except ProbackupException, e:
|
except ProbackupException, e:
|
||||||
self.assertEqual(True, 'could not read WAL record' in e.message)
|
self.assertEqual(True, 'is absent' in e.message)
|
||||||
node.stop()
|
node.stop()
|
||||||
|
Reference in New Issue
Block a user