@@ -246,7 +246,7 @@ def test_restore_to_xid_5(self):
246
246
247
247
def test_restore_full_ptrack_6 (self ):
248
248
"""recovery to latest from full + ptrack backups"""
249
- node = self .make_bnode ('restore_full_ptrack_6' , base_dir = "tmp_dirs/restore/restore_full_ptrack_6 " )
249
+ node = self .make_bnode ('restore_full_ptrack_6' , base_dir = "tmp_dirs/restore/full_ptrack_6 " )
250
250
node .start ()
251
251
self .assertEqual (self .init_pb (node ), six .b ("" ))
252
252
node .pgbench_init (scale = 2 )
@@ -290,3 +290,283 @@ def test_restore_full_ptrack_6(self):
290
290
self .assertEqual (before , after )
291
291
292
292
node .stop ()
293
+
294
+ def test_restore_full_ptrack_ptrack_7 (self ):
295
+ """recovery to latest from full + ptrack + ptrack backups"""
296
+ node = self .make_bnode ('restore_full_ptrack_ptrack_7' , base_dir = "tmp_dirs/restore/full_ptrack_ptrack_7" )
297
+ node .start ()
298
+ self .assertEqual (self .init_pb (node ), six .b ("" ))
299
+ node .pgbench_init (scale = 2 )
300
+ is_ptrack = node .execute ("postgres" , "SELECT proname FROM pg_proc WHERE proname='pg_ptrack_clear'" )
301
+ if not is_ptrack :
302
+ node .stop ()
303
+ self .skipTest ("ptrack not supported" )
304
+ return
305
+
306
+ node .append_conf ("postgresql.conf" , "ptrack_enable = on" )
307
+ node .restart ()
308
+
309
+ with open (path .join (node .logs_dir , "backup_1.log" ), "wb" ) as backup_log :
310
+ backup_log .write (self .backup_pb (node , backup_type = "full" , options = ["--verbose" ]))
311
+
312
+ pgbench = node .pgbench (stdout = subprocess .PIPE , stderr = subprocess .STDOUT )
313
+ pgbench .wait ()
314
+ pgbench .stdout .close ()
315
+
316
+ with open (path .join (node .logs_dir , "backup_2.log" ), "wb" ) as backup_log :
317
+ backup_log .write (self .backup_pb (node , backup_type = "ptrack" , options = ["--verbose" ]))
318
+
319
+ pgbench = node .pgbench (stdout = subprocess .PIPE , stderr = subprocess .STDOUT )
320
+ pgbench .wait ()
321
+ pgbench .stdout .close ()
322
+
323
+ with open (path .join (node .logs_dir , "backup_3.log" ), "wb" ) as backup_log :
324
+ backup_log .write (self .backup_pb (node , backup_type = "ptrack" , options = ["--verbose" ]))
325
+
326
+ before = node .execute ("postgres" , "SELECT * FROM pgbench_branches" )
327
+
328
+ node .pg_ctl ("stop" , {
329
+ "-D" : node .data_dir ,
330
+ "-w" : None ,
331
+ "-m" : "immediate"
332
+ })
333
+
334
+ with open (path .join (node .logs_dir , "restore_1.log" ), "wb" ) as restore_log :
335
+ restore_log .write (self .restore_pb (node , options = ["-j" , "4" , "--verbose" ]))
336
+
337
+ node .pg_ctl ("start" , {
338
+ "-D" : node .data_dir ,
339
+ "-w" : None ,
340
+ "-t" : "600"
341
+ })
342
+
343
+ after = node .execute ("postgres" , "SELECT * FROM pgbench_branches" )
344
+ self .assertEqual (before , after )
345
+
346
+ node .stop ()
347
+
348
+ def test_restore_full_ptrack_stream_8 (self ):
349
+ """recovery in stream mode to latest from full + ptrack backups"""
350
+ node = self .make_bnode ('restore_full_ptrack_stream_8' , base_dir = "tmp_dirs/restore/full_ptrack_stream_8" )
351
+ node .start ()
352
+ self .assertEqual (self .init_pb (node ), six .b ("" ))
353
+ node .pgbench_init (scale = 2 )
354
+ is_ptrack = node .execute ("postgres" , "SELECT proname FROM pg_proc WHERE proname='pg_ptrack_clear'" )
355
+ if not is_ptrack :
356
+ node .stop ()
357
+ self .skipTest ("ptrack not supported" )
358
+ return
359
+
360
+ node .append_conf ("postgresql.conf" , "ptrack_enable = on" )
361
+ node .restart ()
362
+
363
+ with open (path .join (node .logs_dir , "backup_1.log" ), "wb" ) as backup_log :
364
+ backup_log .write (self .backup_pb (node , backup_type = "full" , options = ["--verbose" , "--stream" ]))
365
+
366
+ pgbench = node .pgbench (stdout = subprocess .PIPE , stderr = subprocess .STDOUT )
367
+ pgbench .wait ()
368
+ pgbench .stdout .close ()
369
+
370
+ with open (path .join (node .logs_dir , "backup_2.log" ), "wb" ) as backup_log :
371
+ backup_log .write (self .backup_pb (node , backup_type = "ptrack" , options = ["--verbose" , "--stream" ]))
372
+
373
+ before = node .execute ("postgres" , "SELECT * FROM pgbench_branches" )
374
+
375
+ node .pg_ctl ("stop" , {
376
+ "-D" : node .data_dir ,
377
+ "-w" : None ,
378
+ "-m" : "immediate"
379
+ })
380
+
381
+ with open (path .join (node .logs_dir , "restore_1.log" ), "wb" ) as restore_log :
382
+ restore_log .write (self .restore_pb (node , options = ["-j" , "4" , "--verbose" ]))
383
+
384
+ node .pg_ctl ("start" , {
385
+ "-D" : node .data_dir ,
386
+ "-w" : None ,
387
+ "-t" : "600"
388
+ })
389
+
390
+ after = node .execute ("postgres" , "SELECT * FROM pgbench_branches" )
391
+ self .assertEqual (before , after )
392
+
393
+ node .stop ()
394
+
395
+ def test_restore_full_ptrack_under_load_9 (self ):
396
+ """recovery to latest from full + page backups with loads when ptrack backup do"""
397
+ node = self .make_bnode ('restore_full_ptrack_under_load_9' , base_dir = "tmp_dirs/restore/full_ptrack_under_load_9" )
398
+ node .start ()
399
+ self .assertEqual (self .init_pb (node ), six .b ("" ))
400
+ node .pgbench_init (scale = 2 )
401
+ is_ptrack = node .execute ("postgres" , "SELECT proname FROM pg_proc WHERE proname='pg_ptrack_clear'" )
402
+ if not is_ptrack :
403
+ node .stop ()
404
+ self .skipTest ("ptrack not supported" )
405
+ return
406
+
407
+ node .append_conf ("postgresql.conf" , "ptrack_enable = on" )
408
+ node .restart ()
409
+
410
+ with open (path .join (node .logs_dir , "backup_1.log" ), "wb" ) as backup_log :
411
+ backup_log .write (self .backup_pb (node , backup_type = "full" , options = ["--verbose" ]))
412
+
413
+ pgbench = node .pgbench (
414
+ stdout = subprocess .PIPE ,
415
+ stderr = subprocess .STDOUT ,
416
+ options = ["-c" , "4" , "-T" , "8" ]
417
+ )
418
+
419
+ with open (path .join (node .logs_dir , "backup_2.log" ), "wb" ) as backup_log :
420
+ backup_log .write (self .backup_pb (node , backup_type = "ptrack" , options = ["--verbose" , "--stream" ]))
421
+
422
+ pgbench .wait ()
423
+ pgbench .stdout .close ()
424
+
425
+ node .execute ("postgres" , "SELECT pg_switch_xlog()" )
426
+
427
+ bbalance = node .execute ("postgres" , "SELECT sum(bbalance) FROM pgbench_branches" )
428
+ delta = node .execute ("postgres" , "SELECT sum(delta) FROM pgbench_history" )
429
+
430
+ self .assertEqual (bbalance , delta )
431
+
432
+ node .pg_ctl ("stop" , {
433
+ "-D" : node .data_dir ,
434
+ "-w" : None ,
435
+ "-m" : "immediate"
436
+ })
437
+
438
+ with open (path .join (node .logs_dir , "restore_1.log" ), "wb" ) as restore_log :
439
+ restore_log .write (self .restore_pb (node , options = ["-j" , "4" , "--verbose" ]))
440
+
441
+ node .pg_ctl ("start" , {
442
+ "-D" : node .data_dir ,
443
+ "-w" : None ,
444
+ "-t" : "600"
445
+ })
446
+
447
+ bbalance = node .execute ("postgres" , "SELECT sum(bbalance) FROM pgbench_branches" )
448
+ delta = node .execute ("postgres" , "SELECT sum(delta) FROM pgbench_history" )
449
+
450
+ self .assertEqual (bbalance , delta )
451
+
452
+ node .stop ()
453
+
454
+ def test_restore_full_under_load_ptrack_10 (self ):
455
+ """recovery to latest from full + page backups with loads when full backup do"""
456
+ node = self .make_bnode ('estore_full_under_load_ptrack_10' , base_dir = "tmp_dirs/restore/full_under_load_ptrack_10" )
457
+ node .start ()
458
+ self .assertEqual (self .init_pb (node ), six .b ("" ))
459
+ node .pgbench_init (scale = 2 )
460
+ is_ptrack = node .execute ("postgres" , "SELECT proname FROM pg_proc WHERE proname='pg_ptrack_clear'" )
461
+ if not is_ptrack :
462
+ node .stop ()
463
+ self .skipTest ("ptrack not supported" )
464
+ return
465
+
466
+ node .append_conf ("postgresql.conf" , "ptrack_enable = on" )
467
+ node .restart ()
468
+
469
+ pgbench = node .pgbench (
470
+ stdout = subprocess .PIPE ,
471
+ stderr = subprocess .STDOUT ,
472
+ options = ["-c" , "4" , "-T" , "8" ]
473
+ )
474
+
475
+ with open (path .join (node .logs_dir , "backup_1.log" ), "wb" ) as backup_log :
476
+ backup_log .write (self .backup_pb (node , backup_type = "full" , options = ["--verbose" ]))
477
+
478
+ pgbench .wait ()
479
+ pgbench .stdout .close ()
480
+
481
+ with open (path .join (node .logs_dir , "backup_2.log" ), "wb" ) as backup_log :
482
+ backup_log .write (self .backup_pb (node , backup_type = "ptrack" , options = ["--verbose" , "--stream" ]))
483
+
484
+ node .execute ("postgres" , "SELECT pg_switch_xlog()" )
485
+
486
+ bbalance = node .execute ("postgres" , "SELECT sum(bbalance) FROM pgbench_branches" )
487
+ delta = node .execute ("postgres" , "SELECT sum(delta) FROM pgbench_history" )
488
+
489
+ self .assertEqual (bbalance , delta )
490
+
491
+ node .pg_ctl ("stop" , {
492
+ "-D" : node .data_dir ,
493
+ "-w" : None ,
494
+ "-m" : "immediate"
495
+ })
496
+
497
+ with open (path .join (node .logs_dir , "restore_1.log" ), "wb" ) as restore_log :
498
+ restore_log .write (self .restore_pb (node , options = ["-j" , "4" , "--verbose" ]))
499
+
500
+ node .pg_ctl ("start" , {
501
+ "-D" : node .data_dir ,
502
+ "-w" : None ,
503
+ "-t" : "600"
504
+ })
505
+
506
+ bbalance = node .execute ("postgres" , "SELECT sum(bbalance) FROM pgbench_branches" )
507
+ delta = node .execute ("postgres" , "SELECT sum(delta) FROM pgbench_history" )
508
+
509
+ self .assertEqual (bbalance , delta )
510
+
511
+ node .stop ()
512
+
513
+ def test_restore_to_xid_inclusive_11 (self ):
514
+ """recovery with target inclusive false"""
515
+ node = self .make_bnode ('estore_to_xid_inclusive_11' , base_dir = "tmp_dirs/restore/restore_to_xid_inclusive_11" )
516
+ node .start ()
517
+ self .assertEqual (self .init_pb (node ), six .b ("" ))
518
+ node .pgbench_init (scale = 2 )
519
+ with node .connect ("postgres" ) as con :
520
+ con .execute ("CREATE TABLE tbl0005 (a text)" )
521
+ con .commit ()
522
+
523
+ with open (path .join (node .logs_dir , "backup_1.log" ), "wb" ) as backup_log :
524
+ backup_log .write (self .backup_pb (node , backup_type = "full" , options = ["--verbose" ]))
525
+
526
+ pgbench = node .pgbench (stdout = subprocess .PIPE , stderr = subprocess .STDOUT )
527
+ pgbench .wait ()
528
+ pgbench .stdout .close ()
529
+
530
+ before = node .execute ("postgres" , "SELECT * FROM pgbench_branches" )
531
+ with node .connect ("postgres" ) as con :
532
+ res = con .execute ("INSERT INTO tbl0005 VALUES ('inserted') RETURNING (xmin)" )
533
+ con .commit ()
534
+ target_xid = res [0 ][0 ]
535
+
536
+ pgbench = node .pgbench (stdout = subprocess .PIPE , stderr = subprocess .STDOUT )
537
+ pgbench .wait ()
538
+ pgbench .stdout .close ()
539
+
540
+ # Enforce segment to be archived to ensure that recovery goes up to the
541
+ # wanted point. There is no way to ensure that all segments needed have
542
+ # been archived up to the xmin point saved earlier without that.
543
+ node .execute ("postgres" , "SELECT pg_switch_xlog()" )
544
+
545
+ node .pg_ctl ("stop" , {
546
+ "-D" : node .data_dir ,
547
+ "-w" : None ,
548
+ "-m" : "fast"
549
+ })
550
+
551
+ with open (path .join (node .logs_dir , "restore_1.log" ), "wb" ) as restore_log :
552
+ restore_log .write (self .restore_pb (
553
+ node ,
554
+ options = [
555
+ "-j" , "4" ,
556
+ "--verbose" ,
557
+ '--xid=%s' % target_xid ,
558
+ "--inclusive=false"
559
+ ]
560
+ ))
561
+
562
+ node .pg_ctl ("start" , {
563
+ "-D" : node .data_dir ,
564
+ "-w" : None ,
565
+ "-t" : "600"
566
+ })
567
+
568
+ after = node .execute ("postgres" , "SELECT * FROM pgbench_branches" )
569
+ self .assertEqual (before , after )
570
+ self .assertEqual (len (node .execute ("postgres" , "SELECT * FROM tbl0005" )), 0 )
571
+
572
+ node .stop ()
0 commit comments