|
22 | 22 | # Disable autovacuum to avoid generating xid during stats update as otherwise
|
23 | 23 | # the new XID could then be replicated to standby at some random point making
|
24 | 24 | # slots at primary lag behind standby during slot sync.
|
25 |
| -$publisher->append_conf('postgresql.conf', 'autovacuum = off'); |
| 25 | +$publisher->append_conf( |
| 26 | + 'postgresql.conf', qq{ |
| 27 | +autovacuum = off |
| 28 | +max_prepared_transactions = 1 |
| 29 | +}); |
26 | 30 | $publisher->start;
|
27 | 31 |
|
28 | 32 | $publisher->safe_psql('postgres',
|
|
33 | 37 | # Create a subscriber node, wait for sync to complete
|
34 | 38 | my $subscriber1 = PostgreSQL::Test::Cluster->new('subscriber1');
|
35 | 39 | $subscriber1->init;
|
| 40 | +$subscriber1->append_conf('postgresql.conf', 'max_prepared_transactions = 1'); |
36 | 41 | $subscriber1->start;
|
37 | 42 |
|
38 | 43 | # Capture the time before the logical failover slot is created on the
|
|
830 | 835 | "'sb1_slot'");
|
831 | 836 | $primary->reload;
|
832 | 837 |
|
| 838 | +################################################## |
| 839 | +# Test the synchronization of the two_phase setting for a subscription with the |
| 840 | +# standby. Additionally, prepare a transaction before enabling the two_phase |
| 841 | +# option; subsequent tests will verify if it can be correctly replicated to the |
| 842 | +# subscriber after committing it on the promoted standby. |
| 843 | +################################################## |
| 844 | + |
| 845 | +$standby1->start; |
| 846 | + |
| 847 | +# Prepare a transaction |
| 848 | +$primary->safe_psql( |
| 849 | + 'postgres', qq[ |
| 850 | + BEGIN; |
| 851 | + INSERT INTO tab_int values(0); |
| 852 | + PREPARE TRANSACTION 'test_twophase_slotsync'; |
| 853 | +]); |
| 854 | + |
| 855 | +$primary->wait_for_replay_catchup($standby1); |
| 856 | +$primary->wait_for_catchup('regress_mysub1'); |
| 857 | + |
| 858 | +# Disable the subscription to allow changing the two_phase option. |
| 859 | +$subscriber1->safe_psql('postgres', |
| 860 | + "ALTER SUBSCRIPTION regress_mysub1 DISABLE"); |
| 861 | + |
| 862 | +# Wait for the replication slot to become inactive on the publisher |
| 863 | +$primary->poll_query_until( |
| 864 | + 'postgres', |
| 865 | + "SELECT COUNT(*) FROM pg_catalog.pg_replication_slots WHERE slot_name = 'lsub1_slot' AND active='f'", |
| 866 | + 1); |
| 867 | + |
| 868 | +# Set two_phase to true and enable the subscription |
| 869 | +$subscriber1->safe_psql( |
| 870 | + 'postgres', qq[ |
| 871 | + ALTER SUBSCRIPTION regress_mysub1 SET (two_phase = true); |
| 872 | + ALTER SUBSCRIPTION regress_mysub1 ENABLE; |
| 873 | +]); |
| 874 | + |
| 875 | +$primary->wait_for_catchup('regress_mysub1'); |
| 876 | + |
| 877 | +my $two_phase_at = $primary->safe_psql('postgres', |
| 878 | + "SELECT two_phase_at from pg_replication_slots WHERE slot_name = 'lsub1_slot';" |
| 879 | +); |
| 880 | + |
| 881 | +# Confirm that two_phase setting of lsub1_slot slot is synced to the standby |
| 882 | +ok( $standby1->poll_query_until( |
| 883 | + 'postgres', |
| 884 | + "SELECT two_phase AND '$two_phase_at' = two_phase_at from pg_replication_slots WHERE slot_name = 'lsub1_slot' AND synced AND NOT temporary;" |
| 885 | + ), |
| 886 | + 'two_phase setting of slot lsub1_slot synced to standby'); |
| 887 | + |
| 888 | +# Confirm that the prepared transaction is not yet replicated to the |
| 889 | +# subscriber. |
| 890 | +$result = $subscriber1->safe_psql('postgres', |
| 891 | + "SELECT count(*) = 0 FROM pg_prepared_xacts;"); |
| 892 | +is($result, 't', |
| 893 | + "the prepared transaction is not replicated to the subscriber"); |
| 894 | + |
833 | 895 | ##################################################
|
834 | 896 | # Promote the standby1 to primary. Confirm that:
|
835 | 897 | # a) the slot 'lsub1_slot' and 'snap_test_slot' are retained on the new primary
|
836 | 898 | # b) logical replication for regress_mysub1 is resumed successfully after failover
|
837 |
| -# c) changes can be consumed from the synced slot 'snap_test_slot' |
| 899 | +# c) changes from the transaction prepared 'test_twophase_slotsync' can be |
| 900 | +# consumed from the synced slot 'snap_test_slot' once committed on the new |
| 901 | +# primary. |
| 902 | +# d) changes can be consumed from the synced slot 'snap_test_slot' |
838 | 903 | ##################################################
|
839 |
| -$standby1->start; |
840 | 904 | $primary->wait_for_replay_catchup($standby1);
|
841 | 905 |
|
842 | 906 | # Capture the time before the standby is promoted
|
|
876 | 940 | 't',
|
877 | 941 | 'synced slot retained on the new primary');
|
878 | 942 |
|
| 943 | +# Commit the prepared transaction |
| 944 | +$standby1->safe_psql('postgres', |
| 945 | + "COMMIT PREPARED 'test_twophase_slotsync';"); |
| 946 | +$standby1->wait_for_catchup('regress_mysub1'); |
| 947 | + |
| 948 | +# Confirm that the prepared transaction is replicated to the subscriber |
| 949 | +is($subscriber1->safe_psql('postgres', q{SELECT count(*) FROM tab_int;}), |
| 950 | + "11", 'prepared data replicated from the new primary'); |
| 951 | + |
879 | 952 | # Insert data on the new primary
|
880 | 953 | $standby1->safe_psql('postgres',
|
881 | 954 | "INSERT INTO tab_int SELECT generate_series(11, 20);");
|
882 | 955 | $standby1->wait_for_catchup('regress_mysub1');
|
883 | 956 |
|
884 | 957 | # Confirm that data in tab_int replicated on the subscriber
|
885 | 958 | is($subscriber1->safe_psql('postgres', q{SELECT count(*) FROM tab_int;}),
|
886 |
| - "20", 'data replicated from the new primary'); |
| 959 | + "21", 'data replicated from the new primary'); |
887 | 960 |
|
888 | 961 | # Consume the data from the snap_test_slot. The synced slot should reach a
|
889 | 962 | # consistent point by restoring the snapshot at the restart_lsn serialized
|
|
0 commit comments