@@ -41,6 +41,25 @@ sub generate_db
41
41
return $dbname ;
42
42
}
43
43
44
+ # Wait for subscriptions on the subscriber to catch up all changes.
45
+ sub wait_for_all_subscriptions_caught_up
46
+ {
47
+ my ($node_p , $node_s ) = @_ ;
48
+
49
+ # Get subscription names
50
+ my $result = $node_s -> safe_psql(
51
+ ' postgres' , qq(
52
+ SELECT subname FROM pg_subscription WHERE subname ~ '^pg_createsubscriber_'
53
+ ) );
54
+ my @subnames = split (" \n " , $result );
55
+
56
+ # Wait for all subscriptions to catch up
57
+ foreach my $subname (@subnames )
58
+ {
59
+ $node_p -> wait_for_catchup($subname );
60
+ }
61
+ }
62
+
44
63
#
45
64
# Test mandatory options
46
65
command_fails([' pg_createsubscriber' ],
@@ -386,6 +405,23 @@ sub generate_db
386
405
],
387
406
' run pg_createsubscriber without --databases' );
388
407
408
+ # run pg_createsubscriber with '--all' and '--database' and verify the
409
+ # failure
410
+ command_fails_like(
411
+ [
412
+ ' pg_createsubscriber' ,
413
+ ' --verbose' ,
414
+ ' --dry-run' ,
415
+ ' --pgdata' => $node_s -> data_dir,
416
+ ' --publisher-server' => $node_p -> connstr($db1 ),
417
+ ' --socketdir' => $node_s -> host,
418
+ ' --subscriber-port' => $node_s -> port,
419
+ ' --all' ,
420
+ ' --database' => $db1 ,
421
+ ],
422
+ qr / --database cannot be used with --all/ ,
423
+ ' fail if --database is used with --all' );
424
+
389
425
# run pg_createsubscriber with '--database' and '--all' without '--dry-run'
390
426
# and verify the failure
391
427
command_fails_like(
@@ -419,6 +455,40 @@ sub generate_db
419
455
qr / --publication cannot be used with --all/ ,
420
456
' fail if --publication is used with --all' );
421
457
458
+ # run pg_createsubscriber with '--replication-slot' and '--all' and
459
+ # verify the failure
460
+ command_fails_like(
461
+ [
462
+ ' pg_createsubscriber' ,
463
+ ' --verbose' ,
464
+ ' --dry-run' ,
465
+ ' --pgdata' => $node_s -> data_dir,
466
+ ' --publisher-server' => $node_p -> connstr($db1 ),
467
+ ' --socketdir' => $node_s -> host,
468
+ ' --subscriber-port' => $node_s -> port,
469
+ ' --replication-slot' => ' replslot1' ,
470
+ ' --all' ,
471
+ ],
472
+ qr / --replication-slot cannot be used with --all/ ,
473
+ ' fail if --replication-slot is used with --all' );
474
+
475
+ # run pg_createsubscriber with '--subscription' and '--all' and
476
+ # verify the failure
477
+ command_fails_like(
478
+ [
479
+ ' pg_createsubscriber' ,
480
+ ' --verbose' ,
481
+ ' --dry-run' ,
482
+ ' --pgdata' => $node_s -> data_dir,
483
+ ' --publisher-server' => $node_p -> connstr($db1 ),
484
+ ' --socketdir' => $node_s -> host,
485
+ ' --subscriber-port' => $node_s -> port,
486
+ ' --all' ,
487
+ ' --subscription' => ' sub1' ,
488
+ ],
489
+ qr / --subscription cannot be used with --all/ ,
490
+ ' fail if --subscription is used with --all' );
491
+
422
492
# run pg_createsubscriber with '--all' option
423
493
my ($stdout , $stderr ) = run_command(
424
494
[
@@ -502,16 +572,7 @@ sub generate_db
502
572
) );
503
573
is($result , qq( 0) , ' pre-existing subscription was dropped' );
504
574
505
- # Get subscription names
506
- $result = $node_s -> safe_psql(
507
- ' postgres' , qq(
508
- SELECT subname FROM pg_subscription WHERE subname ~ '^pg_createsubscriber_'
509
- ) );
510
- my @subnames = split (" \n " , $result );
511
-
512
- # Wait subscriber to catch up
513
- $node_s -> wait_for_subscription_sync($node_p , $subnames [0]);
514
- $node_s -> wait_for_subscription_sync($node_p , $subnames [1]);
575
+ wait_for_all_subscriptions_caught_up($node_p , $node_s );
515
576
516
577
# Confirm the failover slot has been removed
517
578
$result = $node_s -> safe_psql($db1 ,
@@ -537,10 +598,80 @@ sub generate_db
537
598
' SELECT system_identifier FROM pg_control_system()' );
538
599
ok($sysid_p != $sysid_s , ' system identifier was changed' );
539
600
601
+ $node_s -> stop;
602
+
603
+ # Drop the database $db2 to verify subscriptions are handled correctly
604
+ $node_p -> safe_psql(' postgres' , " DROP DATABASE \" $db2 \" " );
605
+
606
+ # On node P create a test table
607
+ $node_p -> safe_psql(' postgres' , ' CREATE TABLE tbl1 (a text)' );
608
+
609
+ # Set up node U as standby linking to node P
610
+ $node_p -> backup(' backup_3' );
611
+ my $node_u = PostgreSQL::Test::Cluster-> new(' node_u' );
612
+ $node_u -> init_from_backup($node_p , ' backup_3' , has_streaming => 1);
613
+ $node_u -> set_standby_mode();
614
+
615
+ # run pg_createsubscriber with '--all' option without '--dry-run'
616
+ command_ok(
617
+ [
618
+ ' pg_createsubscriber' ,
619
+ ' --verbose' ,
620
+ ' --recovery-timeout' => $PostgreSQL::Test::Utils::timeout_default ,
621
+ ' --pgdata' => $node_u -> data_dir,
622
+ ' --publisher-server' => $node_p -> connstr($db1 ),
623
+ ' --socketdir' => $node_u -> host,
624
+ ' --subscriber-port' => $node_u -> port,
625
+ ' --all' ,
626
+ ],
627
+ ' run pg_createsubscriber with --all' );
628
+
629
+ $node_u -> start;
630
+
631
+ # Verify that user databases (postgres, $db1) got subscriptions.
632
+ $result = $node_u -> safe_psql(
633
+ ' postgres' ,
634
+ ' SELECT datname FROM pg_subscription,
635
+ pg_database WHERE subdbid = pg_database.oid and datistemplate = \' f\' ORDER BY pg_database.oid'
636
+ );
637
+ is( $result , " postgres
638
+ $db1 " , ' subscription is created on the required databases' );
639
+
640
+ # Verify template databases do not have subscriptions
641
+ $result = $node_u -> safe_psql(
642
+ ' postgres' ,
643
+ " SELECT count(*) FROM pg_subscription, pg_database
644
+ WHERE subdbid = pg_database.oid and datistemplate = 't';"
645
+ );
646
+ is($result , ' 0' , ' subscription is not created on template databases' );
647
+
648
+ # Verify logical replication works for all databases
649
+ # Insert rows on node P
650
+ $node_p -> safe_psql(' postgres' ,
651
+ " INSERT INTO tbl1 VALUES('row in database postgres')" );
652
+ $node_p -> safe_psql($db1 , " INSERT INTO tbl1 VALUES('fourth row')" );
653
+
654
+ wait_for_all_subscriptions_caught_up($node_p , $node_u );
655
+
656
+ # Check result in database 'postgres' of node U
657
+ $result = $node_u -> safe_psql(' postgres' , ' SELECT * FROM tbl1' );
658
+ is( $result ,
659
+ qq( row in database postgres) ,
660
+ " logical replication works in database postgres" );
661
+
662
+ # Check result in database $db1 of node U
663
+ $result = $node_u -> safe_psql($db1 , ' SELECT * FROM tbl1' );
664
+ is( $result , qq( first row
665
+ second row
666
+ third row
667
+ fourth row) ,
668
+ " logical replication works in database $db1 " );
669
+
540
670
# clean up
541
671
$node_p -> teardown_node;
542
672
$node_s -> teardown_node;
543
673
$node_t -> teardown_node;
674
+ $node_u -> teardown_node;
544
675
$node_f -> teardown_node;
545
676
546
677
done_testing();
0 commit comments