|
9 | 9 | import hashlib |
10 | 10 | import shutil |
11 | 11 | import json |
12 | | -from testgres import QueryException |
| 12 | +from testgres import QueryException, StartNodeException |
13 | 13 |
|
14 | 14 |
|
15 | 15 | module_name = 'incr_restore' |
@@ -2436,3 +2436,82 @@ def test_incremental_pg_filenode_map(self): |
2436 | 2436 | self.del_test_dir(module_name, fname) |
2437 | 2437 |
|
2438 | 2438 | # check that MinRecPoint and BackupStartLsn are correctly used in case of --incrementa-lsn |
| 2439 | + |
| 2440 | + |
| 2441 | + # @unittest.skip("skip") |
| 2442 | + def test_incr_restore_issue_313(self): |
| 2443 | + """ |
| 2444 | + Check that failed incremental restore can be restarted |
| 2445 | + """ |
| 2446 | + fname = self.id().split('.')[3] |
| 2447 | + |
| 2448 | + node = self.make_simple_node( |
| 2449 | + base_dir = os.path.join(module_name, fname, 'node'), |
| 2450 | + set_replication = True, |
| 2451 | + initdb_params = ['--data-checksums']) |
| 2452 | + |
| 2453 | + backup_dir = os.path.join(self.tmp_path, module_name, fname, 'backup') |
| 2454 | + self.init_pb(backup_dir) |
| 2455 | + self.add_instance(backup_dir, 'node', node) |
| 2456 | + self.set_archiving(backup_dir, 'node', node) |
| 2457 | + node.slow_start() |
| 2458 | + |
| 2459 | + node.pgbench_init(scale = 50) |
| 2460 | + |
| 2461 | + full_backup_id = self.backup_node(backup_dir, 'node', node, backup_type='full') |
| 2462 | + |
| 2463 | + pgbench = node.pgbench( |
| 2464 | + stdout=subprocess.PIPE, stderr=subprocess.STDOUT, |
| 2465 | + options=['-T', '10', '-c', '1', '--no-vacuum']) |
| 2466 | + pgbench.wait() |
| 2467 | + pgbench.stdout.close() |
| 2468 | + |
| 2469 | + last_backup_id = self.backup_node(backup_dir, 'node', node, backup_type='delta') |
| 2470 | + |
| 2471 | + pgdata = self.pgdata_content(node.data_dir) |
| 2472 | + node.cleanup() |
| 2473 | + |
| 2474 | + self.restore_node(backup_dir, 'node', node, backup_id=full_backup_id) |
| 2475 | + |
| 2476 | + count = 0 |
| 2477 | + filelist = self.get_backup_filelist(backup_dir, 'node', last_backup_id) |
| 2478 | + for file in filelist: |
| 2479 | + # count only nondata files |
| 2480 | + if int(filelist[file]['is_datafile']) == 0 and int(filelist[file]['size']) > 0: |
| 2481 | + count += 1 |
| 2482 | + |
| 2483 | + gdb = self.restore_node(backup_dir, 'node', node, gdb=True, |
| 2484 | + backup_id=last_backup_id, options=['--progress', '--incremental-mode=checksum']) |
| 2485 | + gdb.verbose = False |
| 2486 | + gdb.set_breakpoint('restore_non_data_file') |
| 2487 | + gdb.run_until_break() |
| 2488 | + gdb.continue_execution_until_break(count - 2) |
| 2489 | + gdb.quit() |
| 2490 | + |
| 2491 | + try: |
| 2492 | + node.slow_start() |
| 2493 | + # we should die here because exception is what we expect to happen |
| 2494 | + self.assertEqual( |
| 2495 | + 1, 0, |
| 2496 | + "Expecting Error because backup is not fully restored") |
| 2497 | + except StartNodeException as e: |
| 2498 | + self.assertIn( |
| 2499 | + 'Cannot start node', |
| 2500 | + e.message, |
| 2501 | + '\n Unexpected Error Message: {0}\n CMD: {1}'.format( |
| 2502 | + repr(e.message), self.cmd)) |
| 2503 | + |
| 2504 | + with open(os.path.join(node.logs_dir, 'postgresql.log'), 'r') as f: |
| 2505 | + self.assertIn( |
| 2506 | + "postgres: could not find the database system", |
| 2507 | + f.read()) |
| 2508 | + |
| 2509 | + self.restore_node(backup_dir, 'node', node, |
| 2510 | + backup_id=last_backup_id, options=['--progress', '--incremental-mode=checksum']) |
| 2511 | + node.slow_start() |
| 2512 | + |
| 2513 | + self.compare_pgdata(pgdata, self.pgdata_content(node.data_dir)) |
| 2514 | + |
| 2515 | + # Clean after yourself |
| 2516 | + node.stop() |
| 2517 | + self.del_test_dir(module_name, fname) |
0 commit comments