@@ -85,8 +85,8 @@ def test_backward_compatibility_page(self):
8585 pgbench = node .pgbench (
8686 stdout = subprocess .PIPE ,
8787 stderr = subprocess .STDOUT ,
88- options = ["-c" , "4" , "-T" , "20" ]
89- )
88+ options = ["-c" , "4" , "-T" , "20" ])
89+
9090 pgbench .wait ()
9191 pgbench .stdout .close ()
9292
@@ -105,6 +105,44 @@ def test_backward_compatibility_page(self):
105105 pgdata_restored = self .pgdata_content (node_restored .data_dir )
106106 self .compare_pgdata (pgdata , pgdata_restored )
107107
108+ node .safe_psql (
109+ 'postgres' ,
110+ 'create table tmp as select * from pgbench_accounts where aid < 1000' )
111+
112+ node .safe_psql (
113+ 'postgres' ,
114+ 'delete from pgbench_accounts' )
115+
116+ node .safe_psql (
117+ 'postgres' ,
118+ 'VACUUM' )
119+
120+ self .backup_node (backup_dir , 'node' , node , backup_type = 'page' )
121+
122+ pgdata = self .pgdata_content (node .data_dir )
123+
124+ node_restored .cleanup ()
125+ self .restore_node (
126+ backup_dir , 'node' , node_restored , options = ["-j" , "4" ])
127+
128+ pgdata_restored = self .pgdata_content (node_restored .data_dir )
129+ self .compare_pgdata (pgdata , pgdata_restored )
130+
131+ node .safe_psql (
132+ 'postgres' ,
133+ 'insert into pgbench_accounts select * from pgbench_accounts' )
134+
135+ self .backup_node (backup_dir , 'node' , node , backup_type = 'page' )
136+
137+ pgdata = self .pgdata_content (node .data_dir )
138+
139+ node_restored .cleanup ()
140+ self .restore_node (
141+ backup_dir , 'node' , node_restored , options = ["-j" , "4" ])
142+
143+ pgdata_restored = self .pgdata_content (node_restored .data_dir )
144+ self .compare_pgdata (pgdata , pgdata_restored )
145+
108146 # Clean after yourself
109147 self .del_test_dir (module_name , fname )
110148
@@ -118,8 +156,7 @@ def test_backward_compatibility_delta(self):
118156 base_dir = os .path .join (module_name , fname , 'node' ),
119157 set_replication = True ,
120158 initdb_params = ['--data-checksums' ],
121- pg_options = {
122- 'autovacuum' : 'off' })
159+ pg_options = {'autovacuum' : 'off' })
123160
124161 self .init_pb (backup_dir , old_binary = True )
125162 self .show_pb (backup_dir )
@@ -189,8 +226,7 @@ def test_backward_compatibility_delta(self):
189226 pgbench .wait ()
190227 pgbench .stdout .close ()
191228
192- self .backup_node (
193- backup_dir , 'node' , node , backup_type = 'delta' )
229+ self .backup_node (backup_dir , 'node' , node , backup_type = 'delta' )
194230
195231 if self .paranoia :
196232 pgdata = self .pgdata_content (node .data_dir )
@@ -204,6 +240,44 @@ def test_backward_compatibility_delta(self):
204240 pgdata_restored = self .pgdata_content (node_restored .data_dir )
205241 self .compare_pgdata (pgdata , pgdata_restored )
206242
243+ node .safe_psql (
244+ 'postgres' ,
245+ 'create table tmp as select * from pgbench_accounts where aid < 1000' )
246+
247+ node .safe_psql (
248+ 'postgres' ,
249+ 'delete from pgbench_accounts' )
250+
251+ node .safe_psql (
252+ 'postgres' ,
253+ 'VACUUM' )
254+
255+ self .backup_node (backup_dir , 'node' , node , backup_type = 'delta' )
256+
257+ pgdata = self .pgdata_content (node .data_dir )
258+
259+ node_restored .cleanup ()
260+ self .restore_node (
261+ backup_dir , 'node' , node_restored , options = ["-j" , "4" ])
262+
263+ pgdata_restored = self .pgdata_content (node_restored .data_dir )
264+ self .compare_pgdata (pgdata , pgdata_restored )
265+
266+ node .safe_psql (
267+ 'postgres' ,
268+ 'insert into pgbench_accounts select * from pgbench_accounts' )
269+
270+ self .backup_node (backup_dir , 'node' , node , backup_type = 'delta' )
271+
272+ pgdata = self .pgdata_content (node .data_dir )
273+
274+ node_restored .cleanup ()
275+ self .restore_node (
276+ backup_dir , 'node' , node_restored , options = ["-j" , "4" ])
277+
278+ pgdata_restored = self .pgdata_content (node_restored .data_dir )
279+ self .compare_pgdata (pgdata , pgdata_restored )
280+
207281 # Clean after yourself
208282 self .del_test_dir (module_name , fname )
209283
@@ -530,3 +604,87 @@ def test_backward_compatibility_merge(self):
530604
531605 # Clean after yourself
532606 self .del_test_dir (module_name , fname )
607+
608+ # @unittest.expectedFailure
609+ # @unittest.skip("skip")
610+ def test_backward_compatibility_merge_1 (self ):
611+ """
612+ Create node, take FULL and PAGE backups with old binary,
613+ merge them with new binary.
614+ old binary version =< 2.2.7
615+ """
616+ fname = self .id ().split ('.' )[3 ]
617+ backup_dir = os .path .join (self .tmp_path , module_name , fname , 'backup' )
618+ node = self .make_simple_node (
619+ base_dir = os .path .join (module_name , fname , 'node' ),
620+ set_replication = True ,
621+ initdb_params = ['--data-checksums' ],
622+ pg_options = {'autovacuum' : 'off' })
623+
624+ self .init_pb (backup_dir , old_binary = True )
625+ self .add_instance (backup_dir , 'node' , node , old_binary = True )
626+
627+ self .set_archiving (backup_dir , 'node' , node , old_binary = True )
628+ node .slow_start ()
629+
630+ node .pgbench_init (scale = 1 )
631+
632+ # FULL backup with OLD binary
633+ self .backup_node (
634+ backup_dir , 'node' , node ,
635+ old_binary = True )
636+
637+ pgbench = node .pgbench (
638+ stdout = subprocess .PIPE ,
639+ stderr = subprocess .STDOUT ,
640+ options = ["-c" , "4" , "-T" , "10" ])
641+ pgbench .wait ()
642+ pgbench .stdout .close ()
643+
644+ # PAGE1 backup with OLD binary
645+ backup_id = self .backup_node (
646+ backup_dir , 'node' , node ,
647+ backup_type = 'page' , old_binary = True )
648+
649+ node .safe_psql (
650+ 'postgres' ,
651+ 'DELETE from pgbench_accounts' )
652+
653+ node .safe_psql (
654+ 'postgres' ,
655+ 'VACUUM pgbench_accounts' )
656+
657+ # PAGE2 backup with OLD binary
658+ backup_id = self .backup_node (
659+ backup_dir , 'node' , node ,
660+ backup_type = 'page' , old_binary = True )
661+
662+ # PAGE3 backup with OLD binary
663+ backup_id = self .backup_node (
664+ backup_dir , 'node' , node ,
665+ backup_type = 'page' , old_binary = True )
666+
667+ pgdata = self .pgdata_content (node .data_dir )
668+
669+ # merge chain created by old binary with new binary
670+ output = self .merge_backup (
671+ backup_dir , "node" , backup_id )
672+
673+ # check that in-place is disabled
674+ self .assertIn (
675+ "WARNING: In-place merge is disabled "
676+ "because of program versions mismatch" , output )
677+
678+ # restore merged backup
679+ node_restored = self .make_simple_node (
680+ base_dir = os .path .join (module_name , fname , 'node_restored' ))
681+ node_restored .cleanup ()
682+
683+ self .restore_node (
684+ backup_dir , 'node' , node_restored , options = ["-j" , "4" ])
685+
686+ pgdata_restored = self .pgdata_content (node_restored .data_dir )
687+ self .compare_pgdata (pgdata , pgdata_restored )
688+
689+ # Clean after yourself
690+ self .del_test_dir (module_name , fname )
0 commit comments