@@ -1263,3 +1263,73 @@ def test_page_corruption_heal_via_ptrack_2(self):
1263
1263
1264
1264
# Clean after yourself
1265
1265
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