From 510c9477538bed76cb748241a6035d9b8875e791 Mon Sep 17 00:00:00 2001 From: Dmitriy Kuzmin Date: Mon, 6 Apr 2020 20:59:10 +1000 Subject: [PATCH 1/3] compare parent backup version with current binary version while searching for valid ancestor --- src/backup.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/backup.c b/src/backup.c index bcc74ed3..4b511ca4 100644 --- a/src/backup.c +++ b/src/backup.c @@ -218,6 +218,12 @@ do_backup_instance(PGconn *backup_conn, PGNodeInfo *nodeInfo, bool no_sync) if (prev_backup) { + if (parse_program_version(prev_backup->program_version) > parse_program_version(PROGRAM_VERSION)) + elog(ERROR, "pg_probackup binary version is %s, but backup %s version is %s. " + "pg_probackup do not guarantee to be forward compatible. " + "Please upgrade pg_probackup binary.", + PROGRAM_VERSION, base36enc(prev_backup->start_time), prev_backup->program_version); + char prev_backup_filelist_path[MAXPGPATH]; elog(INFO, "Parent backup: %s", base36enc(prev_backup->start_time)); From 3d836b2215ecd95bb8f29683da2d605e91d2f186 Mon Sep 17 00:00:00 2001 From: Dmitriy Kuzmin Date: Mon, 6 Apr 2020 20:59:56 +1000 Subject: [PATCH 2/3] add probackup_version attribute to tests --- tests/helpers/ptrack_helpers.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tests/helpers/ptrack_helpers.py b/tests/helpers/ptrack_helpers.py index d7ddfa03..0f013490 100644 --- a/tests/helpers/ptrack_helpers.py +++ b/tests/helpers/ptrack_helpers.py @@ -246,6 +246,18 @@ class ProbackupTest(object): print('pg_probackup binary is not found') exit(1) + self.probackup_version = None + + try: + self.probackup_version_output = subprocess.check_output( + [self.probackup_path, "--version"], + stderr=subprocess.STDOUT, + ).decode('utf-8') + except subprocess.CalledProcessError as e: + raise ProbackupException(e.output.decode('utf-8')) + + self.probackup_version = re.search(r"\d+\.\d+\.\d+", self.probackup_version_output).group(0) + if os.name == 'posix': self.EXTERNAL_DIRECTORY_DELIMITER = ':' os.environ['PATH'] = os.path.dirname( From cc8ba20965a2d95393930b3fefecf031f414e254 Mon Sep 17 00:00:00 2001 From: Dmitriy Kuzmin Date: Mon, 6 Apr 2020 21:00:12 +1000 Subject: [PATCH 3/3] add test test_parent_backup_made_by_newer_version --- tests/backup.py | 53 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/tests/backup.py b/tests/backup.py index ef418c97..fc079333 100644 --- a/tests/backup.py +++ b/tests/backup.py @@ -2709,3 +2709,56 @@ class BackupTest(ProbackupTest, unittest.TestCase): # Clean after yourself self.del_test_dir(module_name, fname) + + # @unittest.skip("skip") + def test_parent_backup_made_by_newer_version(self): + """incremental backup with parent made by newer version""" + 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) + self.set_archiving(backup_dir, 'node', node) + node.slow_start() + + backup_id = self.backup_node(backup_dir, 'node', node) + + control_file = os.path.join( + backup_dir, "backups", "node", backup_id, + "backup.control") + + version = self.probackup_version + fake_new_version = str(int(version.split('.')[0]) + 1) + '.0.0' + + with open(control_file, 'r') as f: + data = f.read(); + + data = data.replace(version, fake_new_version) + + with open(control_file, 'w') as f: + f.write(data); + + try: + self.backup_node(backup_dir, 'node', node, backup_type="page") + # we should die here because exception is what we expect to happen + self.assertEqual( + 1, 0, + "Expecting Error because incremental backup should not be possible " + "if parent made by newer version.\n Output: {0} \n CMD: {1}".format( + repr(self.output), self.cmd)) + except ProbackupException as e: + self.assertIn( + "pg_probackup do not guarantee to be forward compatible. " + "Please upgrade pg_probackup binary.", + e.message, + "\n Unexpected Error Message: {0}\n CMD: {1}".format( + repr(e.message), self.cmd)) + + self.assertEqual( + self.show_pb(backup_dir, 'node')[1]['status'], "ERROR") + + # Clean after yourself + self.del_test_dir(module_name, fname)