|
12 | 12 | module_name = 'ptrack'
|
13 | 13 |
|
14 | 14 |
|
15 |
| -class PtrackBackupTest(ProbackupTest, unittest.TestCase): |
| 15 | +class PtrackTest(ProbackupTest, unittest.TestCase): |
16 | 16 |
|
17 | 17 | # @unittest.skip("skip")
|
18 | 18 | # @unittest.expectedFailure
|
@@ -511,6 +511,186 @@ def test_ptrack_get_block(self):
|
511 | 511 | # Clean after yourself
|
512 | 512 | self.del_test_dir(module_name, fname)
|
513 | 513 |
|
| 514 | + # @unittest.skip("skip") |
| 515 | + def test_ptrack_concurrent_get_and_clear_1(self): |
| 516 | + """make node, make full and ptrack stream backups," |
| 517 | + " restore them and check data correctness""" |
| 518 | + fname = self.id().split('.')[3] |
| 519 | + backup_dir = os.path.join(self.tmp_path, module_name, fname, 'backup') |
| 520 | + node = self.make_simple_node( |
| 521 | + base_dir="{0}/{1}/node".format(module_name, fname), |
| 522 | + set_replication=True, |
| 523 | + initdb_params=['--data-checksums'], |
| 524 | + pg_options={ |
| 525 | + 'wal_level': 'replica', |
| 526 | + 'max_wal_senders': '2', |
| 527 | + 'checkpoint_timeout': '300s', |
| 528 | + 'ptrack_enable': 'on' |
| 529 | + } |
| 530 | + ) |
| 531 | + self.init_pb(backup_dir) |
| 532 | + self.add_instance(backup_dir, 'node', node) |
| 533 | + self.set_archiving(backup_dir, 'node', node) |
| 534 | + node.start() |
| 535 | + |
| 536 | + node.safe_psql( |
| 537 | + "postgres", |
| 538 | + "create table t_heap as select i" |
| 539 | + " as id from generate_series(0,1) i" |
| 540 | + ) |
| 541 | + |
| 542 | + self.backup_node(backup_dir, 'node', node, options=['--stream']) |
| 543 | + gdb = self.backup_node( |
| 544 | + backup_dir, 'node', node, backup_type='ptrack', |
| 545 | + options=['--stream', '--log-level-file=verbose'], |
| 546 | + gdb=True |
| 547 | + ) |
| 548 | + |
| 549 | + gdb.set_breakpoint('make_pagemap_from_ptrack') |
| 550 | + gdb.run_until_break() |
| 551 | + |
| 552 | + node.safe_psql( |
| 553 | + "postgres", |
| 554 | + "update t_heap set id = 100500") |
| 555 | + |
| 556 | + tablespace_oid = node.safe_psql( |
| 557 | + "postgres", |
| 558 | + "select oid from pg_tablespace where spcname = 'pg_default'").rstrip() |
| 559 | + |
| 560 | + relfilenode = node.safe_psql( |
| 561 | + "postgres", |
| 562 | + "select 't_heap'::regclass::oid").rstrip() |
| 563 | + |
| 564 | + node.safe_psql( |
| 565 | + "postgres", |
| 566 | + "SELECT pg_ptrack_get_and_clear({0}, {1})".format( |
| 567 | + tablespace_oid, relfilenode)) |
| 568 | + |
| 569 | + gdb.continue_execution_until_exit() |
| 570 | + |
| 571 | + self.backup_node( |
| 572 | + backup_dir, 'node', node, |
| 573 | + backup_type='ptrack', options=['--stream'] |
| 574 | + ) |
| 575 | + if self.paranoia: |
| 576 | + pgdata = self.pgdata_content(node.data_dir) |
| 577 | + |
| 578 | + result = node.safe_psql("postgres", "SELECT * FROM t_heap") |
| 579 | + node.cleanup() |
| 580 | + self.restore_node(backup_dir, 'node', node, options=["-j", "4"]) |
| 581 | + |
| 582 | + # Physical comparison |
| 583 | + if self.paranoia: |
| 584 | + pgdata_restored = self.pgdata_content(node.data_dir) |
| 585 | + self.compare_pgdata(pgdata, pgdata_restored) |
| 586 | + |
| 587 | + node.start() |
| 588 | + # Logical comparison |
| 589 | + self.assertEqual( |
| 590 | + result, |
| 591 | + node.safe_psql("postgres", "SELECT * FROM t_heap") |
| 592 | + ) |
| 593 | + |
| 594 | + # Clean after yourself |
| 595 | + self.del_test_dir(module_name, fname) |
| 596 | + |
| 597 | + # @unittest.skip("skip") |
| 598 | + def test_ptrack_concurrent_get_and_clear_2(self): |
| 599 | + """make node, make full and ptrack stream backups," |
| 600 | + " restore them and check data correctness""" |
| 601 | + fname = self.id().split('.')[3] |
| 602 | + backup_dir = os.path.join(self.tmp_path, module_name, fname, 'backup') |
| 603 | + node = self.make_simple_node( |
| 604 | + base_dir="{0}/{1}/node".format(module_name, fname), |
| 605 | + set_replication=True, |
| 606 | + initdb_params=['--data-checksums'], |
| 607 | + pg_options={ |
| 608 | + 'wal_level': 'replica', |
| 609 | + 'max_wal_senders': '2', |
| 610 | + 'checkpoint_timeout': '300s', |
| 611 | + 'ptrack_enable': 'on' |
| 612 | + } |
| 613 | + ) |
| 614 | + self.init_pb(backup_dir) |
| 615 | + self.add_instance(backup_dir, 'node', node) |
| 616 | + self.set_archiving(backup_dir, 'node', node) |
| 617 | + node.start() |
| 618 | + |
| 619 | + node.safe_psql( |
| 620 | + "postgres", |
| 621 | + "create table t_heap as select i" |
| 622 | + " as id from generate_series(0,1) i" |
| 623 | + ) |
| 624 | + |
| 625 | + self.backup_node(backup_dir, 'node', node, options=['--stream']) |
| 626 | + gdb = self.backup_node( |
| 627 | + backup_dir, 'node', node, backup_type='ptrack', |
| 628 | + options=['--stream', '--log-level-file=verbose'], |
| 629 | + gdb=True |
| 630 | + ) |
| 631 | + |
| 632 | + gdb.set_breakpoint('pthread_create') |
| 633 | + gdb.run_until_break() |
| 634 | + |
| 635 | + node.safe_psql( |
| 636 | + "postgres", |
| 637 | + "update t_heap set id = 100500") |
| 638 | + |
| 639 | + tablespace_oid = node.safe_psql( |
| 640 | + "postgres", |
| 641 | + "select oid from pg_tablespace where spcname = 'pg_default'").rstrip() |
| 642 | + |
| 643 | + relfilenode = node.safe_psql( |
| 644 | + "postgres", |
| 645 | + "select 't_heap'::regclass::oid").rstrip() |
| 646 | + |
| 647 | + node.safe_psql( |
| 648 | + "postgres", |
| 649 | + "SELECT pg_ptrack_get_and_clear({0}, {1})".format( |
| 650 | + tablespace_oid, relfilenode)) |
| 651 | + |
| 652 | + gdb._execute("delete breakpoints") |
| 653 | + gdb.continue_execution_until_exit() |
| 654 | + |
| 655 | + try: |
| 656 | + self.backup_node( |
| 657 | + backup_dir, 'node', node, |
| 658 | + backup_type='ptrack', options=['--stream'] |
| 659 | + ) |
| 660 | + # we should die here because exception is what we expect to happen |
| 661 | + self.assertEqual( |
| 662 | + 1, 0, |
| 663 | + "Expecting Error because of LSN mismatch from ptrack_control " |
| 664 | + "and previous backup ptrack_lsn.\n" |
| 665 | + " Output: {0} \n CMD: {1}".format(repr(self.output), self.cmd)) |
| 666 | + except ProbackupException as e: |
| 667 | + self.assertTrue( |
| 668 | + 'ERROR: LSN from ptrack_control' in e.message, |
| 669 | + '\n Unexpected Error Message: {0}\n CMD: {1}'.format( |
| 670 | + repr(e.message), self.cmd)) |
| 671 | + |
| 672 | + if self.paranoia: |
| 673 | + pgdata = self.pgdata_content(node.data_dir) |
| 674 | + |
| 675 | + result = node.safe_psql("postgres", "SELECT * FROM t_heap") |
| 676 | + node.cleanup() |
| 677 | + self.restore_node(backup_dir, 'node', node, options=["-j", "4"]) |
| 678 | + |
| 679 | + # Physical comparison |
| 680 | + if self.paranoia: |
| 681 | + pgdata_restored = self.pgdata_content(node.data_dir) |
| 682 | + self.compare_pgdata(pgdata, pgdata_restored) |
| 683 | + |
| 684 | + node.start() |
| 685 | + # Logical comparison |
| 686 | + self.assertEqual( |
| 687 | + result, |
| 688 | + node.safe_psql("postgres", "SELECT * FROM t_heap") |
| 689 | + ) |
| 690 | + |
| 691 | + # Clean after yourself |
| 692 | + self.del_test_dir(module_name, fname) |
| 693 | + |
514 | 694 | # @unittest.skip("skip")
|
515 | 695 | def test_ptrack_stream(self):
|
516 | 696 | """make node, make full and ptrack stream backups,
|
|
0 commit comments