|
3 | 3 | use warnings;
|
4 | 4 | use PostgresNode;
|
5 | 5 | use TestLib;
|
6 |
| -use Test::Moretests=>4; |
| 6 | +use Test::Moretests=>22; |
7 | 7 |
|
8 | 8 | # Initialize master node
|
9 | 9 | my$node_master = get_new_node('master');
|
|
58 | 58 | 3,'read-only queries on standby 1');
|
59 | 59 | is($node_standby_2->psql('postgres','INSERT INTO tab_int VALUES (1)'),
|
60 | 60 | 3,'read-only queries on standby 2');
|
| 61 | + |
| 62 | +diag"switching to physical replication slot"; |
| 63 | +# Switch to using a physical replication slot. We can do this without a new |
| 64 | +# backup since physical slots can go backwards if needed. Do so on both |
| 65 | +# standbys. Since we're going to be testing things that affect the slot state, |
| 66 | +# also increase the standby feedback interval to ensure timely updates. |
| 67 | +my ($slotname_1,$slotname_2) = ('standby_1','standby_2'); |
| 68 | +$node_master->append_conf('postgresql.conf',"max_replication_slots = 4\n"); |
| 69 | +$node_master->restart; |
| 70 | +is($node_master->psql('postgres',qq[SELECT pg_create_physical_replication_slot('$slotname_1');]), 0,'physical slot created on master'); |
| 71 | +$node_standby_1->append_conf('recovery.conf',"primary_slot_name =$slotname_1\n"); |
| 72 | +$node_standby_1->append_conf('postgresql.conf',"wal_receiver_status_interval = 1\n"); |
| 73 | +$node_standby_1->append_conf('postgresql.conf',"max_replication_slots = 4\n"); |
| 74 | +$node_standby_1->restart; |
| 75 | +is($node_standby_1->psql('postgres',qq[SELECT pg_create_physical_replication_slot('$slotname_2');]), 0,'physical slot created on intermediate replica'); |
| 76 | +$node_standby_2->append_conf('recovery.conf',"primary_slot_name =$slotname_2\n"); |
| 77 | +$node_standby_2->append_conf('postgresql.conf',"wal_receiver_status_interval = 1\n"); |
| 78 | +$node_standby_2->restart; |
| 79 | + |
| 80 | +subget_slot_xmins |
| 81 | +{ |
| 82 | +my ($node,$slotname) =@_; |
| 83 | +my$slotinfo =$node->slot($slotname); |
| 84 | +return ($slotinfo->{'xmin'},$slotinfo->{'catalog_xmin'}); |
| 85 | +} |
| 86 | + |
| 87 | +# There's no hot standby feedback and there are no logical slots on either peer |
| 88 | +# so xmin and catalog_xmin should be null on both slots. |
| 89 | +my ($xmin,$catalog_xmin) = get_slot_xmins($node_master,$slotname_1); |
| 90 | +is($xmin,'','non-cascaded slot xmin null with no hs_feedback'); |
| 91 | +is($catalog_xmin,'','non-cascaded slot xmin null with no hs_feedback'); |
| 92 | + |
| 93 | +($xmin,$catalog_xmin) = get_slot_xmins($node_standby_1,$slotname_2); |
| 94 | +is($xmin,'','cascaded slot xmin null with no hs_feedback'); |
| 95 | +is($catalog_xmin,'','cascaded slot xmin null with no hs_feedback'); |
| 96 | + |
| 97 | +# Replication still works? |
| 98 | +$node_master->safe_psql('postgres','CREATE TABLE replayed(val integer);'); |
| 99 | + |
| 100 | +subreplay_check |
| 101 | +{ |
| 102 | +my$newval =$node_master->safe_psql('postgres','INSERT INTO replayed(val) SELECT coalesce(max(val),0) + 1 AS newval FROM replayed RETURNING val'); |
| 103 | +$node_master->wait_for_catchup($node_standby_1,'replay',$node_master->lsn('insert')); |
| 104 | +$node_standby_1->wait_for_catchup($node_standby_2,'replay',$node_standby_1->lsn('replay')); |
| 105 | +$node_standby_1->safe_psql('postgres',qq[SELECT 1 FROM replayed WHERE val =$newval]) |
| 106 | +ordie"standby_1 didn't replay master value$newval"; |
| 107 | +$node_standby_2->safe_psql('postgres',qq[SELECT 1 FROM replayed WHERE val =$newval]) |
| 108 | +ordie"standby_2 didn't replay standby_1 value$newval"; |
| 109 | +} |
| 110 | + |
| 111 | +replay_check(); |
| 112 | + |
| 113 | +diag"enabling hot_standby_feedback"; |
| 114 | +# Enable hs_feedback. The slot should gain an xmin. We set the status interval |
| 115 | +# so we'll see the results promptly. |
| 116 | +$node_standby_1->safe_psql('postgres','ALTER SYSTEM SET hot_standby_feedback = on;'); |
| 117 | +$node_standby_1->reload; |
| 118 | +$node_standby_2->safe_psql('postgres','ALTER SYSTEM SET hot_standby_feedback = on;'); |
| 119 | +$node_standby_2->reload; |
| 120 | +replay_check(); |
| 121 | +sleep(2); |
| 122 | + |
| 123 | +($xmin,$catalog_xmin) = get_slot_xmins($node_master,$slotname_1); |
| 124 | +isnt($xmin,'','non-cascaded slot xmin non-null with hs feedback'); |
| 125 | +is($catalog_xmin,'','non-cascaded slot xmin still null with hs_feedback'); |
| 126 | + |
| 127 | +($xmin,$catalog_xmin) = get_slot_xmins($node_standby_1,$slotname_2); |
| 128 | +isnt($xmin,'','cascaded slot xmin non-null with hs feedback'); |
| 129 | +is($catalog_xmin,'','cascaded slot xmin still null with hs_feedback'); |
| 130 | + |
| 131 | +diag"doing some work to advance xmin"; |
| 132 | +formy$i (10000..11000) { |
| 133 | +$node_master->safe_psql('postgres',qq[INSERT INTO tab_int VALUES ($i);]); |
| 134 | +} |
| 135 | +$node_master->safe_psql('postgres','VACUUM;'); |
| 136 | +$node_master->safe_psql('postgres','CHECKPOINT;'); |
| 137 | + |
| 138 | +my ($xmin2,$catalog_xmin2) = get_slot_xmins($node_master,$slotname_1); |
| 139 | +diag"new xmin$xmin2, old xmin$xmin"; |
| 140 | +isnt($xmin2,$xmin,'non-cascaded slot xmin with hs feedback has changed'); |
| 141 | +is($catalog_xmin2,'','non-cascaded slot xmin still null with hs_feedback unchanged'); |
| 142 | + |
| 143 | +($xmin2,$catalog_xmin2) = get_slot_xmins($node_standby_1,$slotname_2); |
| 144 | +diag"new xmin$xmin2, old xmin$xmin"; |
| 145 | +isnt($xmin2,$xmin,'cascaded slot xmin with hs feedback has changed'); |
| 146 | +is($catalog_xmin2,'','cascaded slot xmin still null with hs_feedback unchanged'); |
| 147 | + |
| 148 | +diag"disabling hot_standby_feedback"; |
| 149 | +# Disable hs_feedback. Xmin should be cleared. |
| 150 | +$node_standby_1->safe_psql('postgres','ALTER SYSTEM SET hot_standby_feedback = off;'); |
| 151 | +$node_standby_1->reload; |
| 152 | +$node_standby_2->safe_psql('postgres','ALTER SYSTEM SET hot_standby_feedback = off;'); |
| 153 | +$node_standby_2->reload; |
| 154 | +replay_check(); |
| 155 | +sleep(2); |
| 156 | + |
| 157 | +($xmin,$catalog_xmin) = get_slot_xmins($node_master,$slotname_1); |
| 158 | +is($xmin,'','non-cascaded slot xmin null with hs feedback reset'); |
| 159 | +is($catalog_xmin,'','non-cascaded slot xmin still null with hs_feedback reset'); |
| 160 | + |
| 161 | +($xmin,$catalog_xmin) = get_slot_xmins($node_standby_1,$slotname_2); |
| 162 | +is($xmin,'','cascaded slot xmin null with hs feedback reset'); |
| 163 | +is($catalog_xmin,'','cascaded slot xmin still null with hs_feedback reset'); |