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

Merge branch 'master' into remote_pull

This commit is contained in:
Grigory Smolkin 2019-04-12 14:05:27 +03:00
commit 4193766317
9 changed files with 91 additions and 29 deletions

View File

@ -584,6 +584,15 @@ do_backup_instance(void)
strlen(" with pg_probackup"));
pg_start_backup(label, smooth_checkpoint, &current);
/* For incremental backup check that start_lsn is not from the past */
if (current.backup_mode != BACKUP_MODE_FULL &&
prev_backup->start_lsn > current.start_lsn)
elog(ERROR, "Current START LSN %X/%X is lower than START LSN %X/%X of previous backup %s. "
"It may indicate that we are trying to backup PostgreSQL instance from the past.",
(uint32) (current.start_lsn >> 32), (uint32) (current.start_lsn),
(uint32) (prev_backup->start_lsn >> 32), (uint32) (prev_backup->start_lsn),
base36enc(prev_backup->start_time));
/* Update running backup meta with START LSN */
write_backup(&current);

View File

@ -81,8 +81,8 @@ do_merge(time_t backup_id)
/* It is possible that previous merging was interrupted */
backup->status != BACKUP_STATUS_MERGING &&
backup->status != BACKUP_STATUS_DELETING)
elog(ERROR, "Backup %s has status: %s",
base36enc(backup->start_time), status2str(backup->status));
elog(ERROR, "Backup %s has status: %s",
base36enc(backup->start_time), status2str(backup->status));
if (backup->backup_mode == BACKUP_MODE_FULL)
elog(ERROR, "Backup %s is full backup",
@ -109,10 +109,8 @@ do_merge(time_t backup_id)
if (full_backup->status != BACKUP_STATUS_OK &&
/* It is possible that previous merging was interrupted */
full_backup->status != BACKUP_STATUS_MERGING)
elog(ERROR, "Backup %s has status: %s",
base36enc(full_backup->start_time), status2str(full_backup->status));
//Assert(full_backup_idx != dest_backup_idx);
elog(ERROR, "Backup %s has status: %s",
base36enc(full_backup->start_time), status2str(full_backup->status));
/* form merge list */
while(dest_backup->parent_backup_link)
@ -122,8 +120,8 @@ do_merge(time_t backup_id)
/* It is possible that previous merging was interrupted */
dest_backup->status != BACKUP_STATUS_MERGING &&
dest_backup->status != BACKUP_STATUS_DELETING)
elog(ERROR, "Backup %s has status: %s",
base36enc(dest_backup->start_time), status2str(dest_backup->status));
elog(ERROR, "Backup %s has status: %s",
base36enc(dest_backup->start_time), status2str(dest_backup->status));
parray_append(merge_list, dest_backup);
dest_backup = dest_backup->parent_backup_link;
@ -205,7 +203,8 @@ merge_backups(pgBackup *to_backup, pgBackup *from_backup)
* BACKUP_STATUS_MERGING status.
*/
Assert(from_backup->status == BACKUP_STATUS_OK ||
from_backup->status == BACKUP_STATUS_MERGING);
from_backup->status == BACKUP_STATUS_MERGING ||
from_backup->status == BACKUP_STATUS_DELETING);
pgBackupValidate(from_backup);
if (from_backup->status == BACKUP_STATUS_CORRUPT)
elog(ERROR, "Interrupt merging");

View File

@ -1191,8 +1191,8 @@ XLogThreadWorker(void *arg)
* Consider thread_arg->endSegNo and thread_arg->endpoint only if
* they are valid.
*/
xlogreader->ReadRecPtr == thread_arg->endpoint &&
nextSegNo > thread_arg->endSegNo)
xlogreader->ReadRecPtr >= thread_arg->endpoint &&
nextSegNo >= thread_arg->endSegNo)
break;
}

View File

@ -18,7 +18,7 @@ def load_tests(loader, tests, pattern):
# suite.addTests(loader.loadTestsFromModule(cfs_backup))
# suite.addTests(loader.loadTestsFromModule(cfs_restore))
# suite.addTests(loader.loadTestsFromModule(cfs_validate_backup))
# suite.addTests(loader.loadTestsFromModule(logging))
suite.addTests(loader.loadTestsFromModule(logging))
suite.addTests(loader.loadTestsFromModule(compression))
suite.addTests(loader.loadTestsFromModule(delete))
suite.addTests(loader.loadTestsFromModule(delta))

View File

@ -422,10 +422,10 @@ class ArchiveTest(ProbackupTest, unittest.TestCase):
set_replication=True,
initdb_params=['--data-checksums'],
pg_options={
'max_wal_senders': '2',
'archive_timeout': '10s',
'max_wal_size': '1GB'}
)
'checkpoint_timeout': '30s',
'max_wal_size': '16MB'})
self.init_pb(backup_dir)
# ADD INSTANCE 'MASTER'
self.add_instance(backup_dir, 'master', master)

View File

@ -711,14 +711,12 @@ class DeltaTest(ProbackupTest, unittest.TestCase):
1, 0,
"Expecting Error because we are connecting to deleted database"
"\n Output: {0} \n CMD: {1}".format(
repr(self.output), self.cmd)
)
repr(self.output), self.cmd))
except QueryException as e:
self.assertTrue(
'FATAL: database "db1" does not exist' in e.message,
'\n Unexpected Error Message: {0}\n CMD: {1}'.format(
repr(e.message), self.cmd)
)
repr(e.message), self.cmd))
# Clean after yourself
self.del_test_dir(module_name, fname)
@ -1305,3 +1303,53 @@ class DeltaTest(ProbackupTest, unittest.TestCase):
# Clean after yourself
self.del_test_dir(module_name, fname)
def test_delta_backup_from_past(self):
"""
make node, take FULL stream backup, take DELTA stream backup,
restore FULL backup, try to take second DELTA stream backup
"""
fname = self.id().split('.')[3]
node = self.make_simple_node(
base_dir=os.path.join(module_name, fname, 'node'),
initdb_params=['--data-checksums'])
backup_dir = os.path.join(self.tmp_path, module_name, fname, 'backup')
self.init_pb(backup_dir)
self.add_instance(backup_dir, 'node', node)
node.slow_start()
backup_id = self.backup_node(
backup_dir, 'node', node, options=['--stream'])
node.pgbench_init(scale=3)
# First DELTA
self.backup_node(
backup_dir, 'node', node,
backup_type='delta', options=['--stream'])
# Restore FULL backup
node.cleanup()
self.restore_node(backup_dir, 'node', node, backup_id=backup_id)
node.slow_start()
# Second DELTA backup
try:
self.backup_node(
backup_dir, 'node', node,
backup_type='delta', options=['--stream'])
# we should die here because exception is what we expect to happen
self.assertEqual(
1, 0,
"Expecting Error because we are backing up an instance from the past"
"\n Output: {0} \n CMD: {1}".format(
repr(self.output), self.cmd))
except QueryException as e:
self.assertTrue(
'Insert error message' in e.message,
'\n Unexpected Error Message: {0}\n CMD: {1}'.format(
repr(e.message), self.cmd))
# Clean after yourself
self.del_test_dir(module_name, fname)

View File

@ -39,7 +39,7 @@ pg_probackup - utility to manage backup/recovery of PostgreSQL database.
[--log-directory=log-directory]
[--log-rotation-size=log-rotation-size]
[--log-rotation-age=log-rotation-age]
[--delete-expired] [--delete-wal]
[--delete-expired] [--delete-wal] [--merge-expired]
[--retention-redundancy=retention-redundancy]
[--retention-window=retention-window]
[--compress]
@ -51,16 +51,19 @@ pg_probackup - utility to manage backup/recovery of PostgreSQL database.
[--master-port=port] [--master-user=user_name]
[--replica-timeout=timeout]
[--skip-block-validation]
[--external-dirs=external-directory-path]
pg_probackup restore -B backup-path --instance=instance_name
[-D pgdata-path] [-i backup-id] [--progress]
[-D pgdata-path] [-i backup-id] [-j num-threads]
[--time=time|--xid=xid|--lsn=lsn [--inclusive=boolean]]
[--timeline=timeline] [-T OLDDIR=NEWDIR]
[--timeline=timeline] [-T OLDDIR=NEWDIR] [--progress]
[--external-mapping=OLDDIR=NEWDIR]
[--immediate] [--recovery-target-name=target-name]
[--recovery-target-action=pause|promote|shutdown]
[--restore-as-replica]
[--no-validate]
[--skip-block-validation]
[--skip-external-dirs]
pg_probackup validate -B backup-path [--instance=instance_name]
[-i backup-id] [--progress] [-j num-threads]
@ -74,10 +77,11 @@ pg_probackup - utility to manage backup/recovery of PostgreSQL database.
[--format=format]
pg_probackup delete -B backup-path --instance=instance_name
[--wal] [-i backup-id | --expired]
[--wal] [-i backup-id | --expired | --merge-expired]
[--dry-run]
pg_probackup merge -B backup-path --instance=instance_name
-i backup-id
-i backup-id [--progress] [-j num-threads]
pg_probackup add-instance -B backup-path -D pgdata-path
--instance=instance_name

View File

@ -1197,7 +1197,7 @@ class MergeTest(ProbackupTest, unittest.TestCase):
def test_continue_failed_merge_2(self):
"""
Check that failed MERGE on delete can`t be continued
Check that failed MERGE on delete can be continued
"""
fname = self.id().split('.')[3]
backup_dir = os.path.join(self.tmp_path, module_name, fname, 'backup')
@ -1253,6 +1253,8 @@ class MergeTest(ProbackupTest, unittest.TestCase):
backup_id_deleted = self.show_pb(backup_dir, "node")[1]["id"]
# TODO check that full backup has meta info is equal to DELETTING
# Try to continue failed MERGE
self.merge_backup(backup_dir, "node", backup_id)
# Clean after yourself

View File

@ -141,10 +141,10 @@ class ReplicaTest(ProbackupTest, unittest.TestCase):
set_replication=True,
initdb_params=['--data-checksums'],
pg_options={
'wal_level': 'replica',
'max_wal_senders': '2',
'archive_timeout': '10s'}
)
'archive_timeout': '10s',
'checkpoint_timeout': '30s',
'max_wal_size': '16MB'})
self.init_pb(backup_dir)
self.add_instance(backup_dir, 'master', master)
self.set_archiving(backup_dir, 'master', master)