@@ -1263,3 +1263,73 @@ def test_page_corruption_heal_via_ptrack_2(self):
12631263
12641264 # Clean after yourself
12651265 self .del_test_dir (module_name , fname )
1266+
1267+ def test_delta_nullified_heap_page_backup (self ):
1268+ """
1269+ make node, take full backup, nullify some heap block,
1270+ take delta backup, restore, physically compare pgdata`s
1271+ """
1272+ fname = self .id ().split ('.' )[3 ]
1273+ node = self .make_simple_node (
1274+ base_dir = "{0}/{1}/node" .format (module_name , fname ),
1275+ initdb_params = ['--data-checksums' ],
1276+ pg_options = {'wal_level' : 'replica' }
1277+ )
1278+ backup_dir = os .path .join (self .tmp_path , module_name , fname , 'backup' )
1279+ self .init_pb (backup_dir )
1280+ self .add_instance (backup_dir , 'node' , node )
1281+ self .set_archiving (backup_dir , 'node' , node )
1282+ node .slow_start ()
1283+
1284+ node .pgbench_init (scale = 1 )
1285+
1286+ file_path = node .safe_psql (
1287+ "postgres" ,
1288+ "select pg_relation_filepath('pgbench_accounts')" ).rstrip ()
1289+
1290+ node .safe_psql (
1291+ "postgres" ,
1292+ "CHECKPOINT" )
1293+
1294+ self .backup_node (
1295+ backup_dir , 'node' , node )
1296+
1297+ # Nullify some block in PostgreSQL
1298+ file = os .path .join (node .data_dir , file_path )
1299+
1300+ with open (file , 'r+b' , 0 ) as f :
1301+ f .seek (8192 )
1302+ f .write (b"\x00 " * 8192 )
1303+ f .flush ()
1304+ f .close
1305+
1306+ self .backup_node (
1307+ backup_dir , 'node' , node ,
1308+ backup_type = 'delta' , options = ["--log-level-file=verbose" ])
1309+
1310+ if self .paranoia :
1311+ pgdata = self .pgdata_content (node .data_dir )
1312+
1313+ log_file_path = os .path .join (backup_dir , "log" , "pg_probackup.log" )
1314+ with open (log_file_path ) as f :
1315+ self .assertTrue ("LOG: File: {0} blknum 1, empty page" .format (
1316+ file ) in f .read ())
1317+ self .assertFalse ("Skipping blknum: 1 in file: {0}" .format (
1318+ file ) in f .read ())
1319+
1320+ # Restore DELTA backup
1321+ node_restored = self .make_simple_node (
1322+ base_dir = "{0}/{1}/node_restored" .format (module_name , fname ),
1323+ )
1324+ node_restored .cleanup ()
1325+
1326+ self .restore_node (
1327+ backup_dir , 'node' , node_restored
1328+ )
1329+
1330+ if self .paranoia :
1331+ pgdata_restored = self .pgdata_content (node_restored .data_dir )
1332+ self .compare_pgdata (pgdata , pgdata_restored )
1333+
1334+ # Clean after yourself
1335+ self .del_test_dir (module_name , fname )
0 commit comments