@@ -309,6 +309,11 @@ def test_backward_compatibility_ptrack(self):
309309 self .set_archiving (backup_dir , 'node' , node , old_binary = True )
310310 node .slow_start ()
311311
312+ if node .major_version >= 12 :
313+ node .safe_psql (
314+ "postgres" ,
315+ "CREATE EXTENSION ptrack" )
316+
312317 node .pgbench_init (scale = 10 )
313318
314319 # FULL backup with old binary
@@ -802,6 +807,196 @@ def test_backward_compatibility_merge_2(self):
802807 # Clean after yourself
803808 self .del_test_dir (module_name , fname )
804809
810+ # @unittest.expectedFailure
811+ # @unittest.skip("skip")
812+ def test_backward_compatibility_merge_3 (self ):
813+ """
814+ Create node, take FULL and PAGE backups with old binary,
815+ merge them with new binary.
816+ old binary version =< 2.2.7
817+ """
818+ fname = self .id ().split ('.' )[3 ]
819+ backup_dir = os .path .join (self .tmp_path , module_name , fname , 'backup' )
820+ node = self .make_simple_node (
821+ base_dir = os .path .join (module_name , fname , 'node' ),
822+ set_replication = True ,
823+ initdb_params = ['--data-checksums' ],
824+ pg_options = {'autovacuum' : 'off' })
825+
826+ self .init_pb (backup_dir , old_binary = True )
827+ self .add_instance (backup_dir , 'node' , node , old_binary = True )
828+
829+ self .set_archiving (backup_dir , 'node' , node , old_binary = True )
830+ node .slow_start ()
831+
832+ node .pgbench_init (scale = 50 )
833+
834+ node .safe_psql (
835+ 'postgres' ,
836+ 'VACUUM pgbench_accounts' )
837+
838+ node_restored = self .make_simple_node (
839+ base_dir = os .path .join (module_name , fname , 'node_restored' ))
840+
841+ # FULL backup with OLD binary
842+ self .backup_node (
843+ backup_dir , 'node' , node , old_binary = True , options = ['--compress' ])
844+
845+ pgbench = node .pgbench (
846+ stdout = subprocess .PIPE ,
847+ stderr = subprocess .STDOUT ,
848+ options = ["-c" , "1" , "-T" , "10" , "--no-vacuum" ])
849+ pgbench .wait ()
850+ pgbench .stdout .close ()
851+
852+ # PAGE1 backup with OLD binary
853+ page1 = self .backup_node (
854+ backup_dir , 'node' , node ,
855+ backup_type = 'page' , old_binary = True , options = ['--compress' ])
856+
857+ pgdata1 = self .pgdata_content (node .data_dir )
858+
859+ node .safe_psql (
860+ 'postgres' ,
861+ "DELETE from pgbench_accounts where ctid > '(10,1)'" )
862+
863+ # PAGE2 backup with OLD binary
864+ page2 = self .backup_node (
865+ backup_dir , 'node' , node ,
866+ backup_type = 'page' , old_binary = True , options = ['--compress' ])
867+
868+ pgdata2 = self .pgdata_content (node .data_dir )
869+
870+ # PAGE3 backup with OLD binary
871+ page3 = self .backup_node (
872+ backup_dir , 'node' , node ,
873+ backup_type = 'page' , old_binary = True , options = ['--compress' ])
874+
875+ pgdata3 = self .pgdata_content (node .data_dir )
876+
877+ pgbench = node .pgbench (
878+ stdout = subprocess .PIPE ,
879+ stderr = subprocess .STDOUT ,
880+ options = ["-c" , "1" , "-T" , "10" , "--no-vacuum" ])
881+ pgbench .wait ()
882+ pgbench .stdout .close ()
883+
884+ # PAGE4 backup with NEW binary
885+ page4 = self .backup_node (
886+ backup_dir , 'node' , node , backup_type = 'page' , options = ['--compress' ])
887+ pgdata4 = self .pgdata_content (node .data_dir )
888+
889+ # merge backups one by one and check data correctness
890+ # merge PAGE1
891+ self .merge_backup (
892+ backup_dir , "node" , page1 , options = ['--log-level-file=VERBOSE' ])
893+
894+ # check data correctness for PAGE1
895+ node_restored .cleanup ()
896+ self .restore_node (
897+ backup_dir , 'node' , node_restored , backup_id = page1 ,
898+ options = ['--log-level-file=VERBOSE' ])
899+ pgdata_restored = self .pgdata_content (node_restored .data_dir )
900+ self .compare_pgdata (pgdata1 , pgdata_restored )
901+
902+ # merge PAGE2
903+ self .merge_backup (backup_dir , "node" , page2 )
904+
905+ # check data correctness for PAGE2
906+ node_restored .cleanup ()
907+ self .restore_node (backup_dir , 'node' , node_restored , backup_id = page2 )
908+ pgdata_restored = self .pgdata_content (node_restored .data_dir )
909+ self .compare_pgdata (pgdata2 , pgdata_restored )
910+
911+ # merge PAGE3
912+ self .show_pb (backup_dir , 'node' , page3 )
913+ self .merge_backup (backup_dir , "node" , page3 )
914+ self .show_pb (backup_dir , 'node' , page3 )
915+
916+ # check data correctness for PAGE3
917+ node_restored .cleanup ()
918+ self .restore_node (backup_dir , 'node' , node_restored , backup_id = page3 )
919+ pgdata_restored = self .pgdata_content (node_restored .data_dir )
920+ self .compare_pgdata (pgdata3 , pgdata_restored )
921+
922+ # merge PAGE4
923+ self .merge_backup (backup_dir , "node" , page4 )
924+
925+ # check data correctness for PAGE4
926+ node_restored .cleanup ()
927+ self .restore_node (backup_dir , 'node' , node_restored , backup_id = page4 )
928+ pgdata_restored = self .pgdata_content (node_restored .data_dir )
929+ self .compare_pgdata (pgdata4 , pgdata_restored )
930+
931+ # Clean after yourself
932+ self .del_test_dir (module_name , fname )
933+
934+ # @unittest.expectedFailure
935+ # @unittest.skip("skip")
936+ def test_backward_compatibility_merge_4 (self ):
937+ """
938+ Start merge between minor version, crash and retry it.
939+ old binary version =< 2.2.7
940+ """
941+ fname = self .id ().split ('.' )[3 ]
942+ backup_dir = os .path .join (self .tmp_path , module_name , fname , 'backup' )
943+ node = self .make_simple_node (
944+ base_dir = os .path .join (module_name , fname , 'node' ),
945+ set_replication = True ,
946+ initdb_params = ['--data-checksums' ],
947+ pg_options = {'autovacuum' : 'off' })
948+
949+ self .init_pb (backup_dir , old_binary = True )
950+ self .add_instance (backup_dir , 'node' , node , old_binary = True )
951+
952+ self .set_archiving (backup_dir , 'node' , node , old_binary = True )
953+ node .slow_start ()
954+
955+ node .pgbench_init (scale = 20 )
956+
957+ node .safe_psql (
958+ 'postgres' ,
959+ 'VACUUM pgbench_accounts' )
960+
961+ node_restored = self .make_simple_node (
962+ base_dir = os .path .join (module_name , fname , 'node_restored' ))
963+
964+ # FULL backup with OLD binary
965+ self .backup_node (
966+ backup_dir , 'node' , node , old_binary = True , options = ['--compress' ])
967+
968+ pgbench = node .pgbench (
969+ stdout = subprocess .PIPE ,
970+ stderr = subprocess .STDOUT ,
971+ options = ["-c" , "1" , "-T" , "20" , "--no-vacuum" ])
972+ pgbench .wait ()
973+ pgbench .stdout .close ()
974+
975+ # PAGE backup with NEW binary
976+ page_id = self .backup_node (
977+ backup_dir , 'node' , node , backup_type = 'page' , options = ['--compress' ])
978+ pgdata = self .pgdata_content (node .data_dir )
979+
980+ # merge PAGE4
981+ gdb = self .merge_backup (backup_dir , "node" , page_id , gdb = True )
982+
983+ gdb .set_breakpoint ('rename' )
984+ gdb .run_until_break ()
985+ gdb .continue_execution_until_break (1000 )
986+ gdb ._execute ('signal SIGKILL' )
987+
988+ self .merge_backup (backup_dir , "node" , page_id )
989+
990+ # check data correctness for PAGE
991+ node_restored .cleanup ()
992+ self .restore_node (backup_dir , 'node' , node_restored , backup_id = page_id )
993+
994+ pgdata_restored = self .pgdata_content (node_restored .data_dir )
995+ self .compare_pgdata (pgdata , pgdata_restored )
996+
997+ # Clean after yourself
998+ self .del_test_dir (module_name , fname )
999+
8051000 # @unittest.skip("skip")
8061001 def test_page_vacuum_truncate (self ):
8071002 """
0 commit comments