|
34 | 34 | use Test::More tests => 3;
|
35 | 35 |
|
36 | 36 | use File::Copy;
|
| 37 | +use File::Path qw(rmtree); |
37 | 38 |
|
38 | 39 | my $tmp_folder = TestLib::tempdir;
|
39 | 40 |
|
|
50 | 51 | $node_1->safe_psql('postgres', 'CREATE TABLE public.bar (t TEXT)');
|
51 | 52 | $node_1->safe_psql('postgres', "INSERT INTO public.bar VALUES ('in both')");
|
52 | 53 |
|
53 |
| - |
54 |
| -# Take backup |
| 54 | +# |
| 55 | +# Create node_2 and node_3 as standbys following node_1 |
| 56 | +# |
55 | 57 | my $backup_name = 'my_backup';
|
56 | 58 | $node_1->backup($backup_name);
|
57 | 59 |
|
58 |
| -# Create streaming standby from backup |
59 | 60 | my $node_2 = get_new_node('node_2');
|
60 | 61 | $node_2->init_from_backup($node_1, $backup_name,
|
61 | 62 | has_streaming => 1);
|
62 | 63 | $node_2->start;
|
63 | 64 |
|
64 |
| -# Create streaming standby from backup |
65 | 65 | my $node_3 = get_new_node('node_3');
|
66 | 66 | $node_3->init_from_backup($node_1, $backup_name,
|
67 | 67 | has_streaming => 1);
|
68 | 68 | $node_3->start;
|
69 | 69 |
|
70 |
| -# Stop node_1 |
| 70 | +# Wait until node 3 has connected and caught up |
| 71 | +my $until_lsn = |
| 72 | + $node_1->safe_psql('postgres', "SELECT pg_current_xlog_location();"); |
| 73 | +my $caughtup_query = |
| 74 | + "SELECT '$until_lsn'::pg_lsn <= pg_last_xlog_replay_location()"; |
| 75 | +$node_3->poll_query_until('postgres', $caughtup_query) |
| 76 | + or die "Timed out while waiting for standby to catch up"; |
71 | 77 |
|
| 78 | +# |
| 79 | +# Swap the roles of node_1 and node_3, so that node_1 follows node_3. |
| 80 | +# |
72 | 81 | $node_1->stop('fast');
|
73 |
| - |
74 |
| -# Promote node_3 |
75 | 82 | $node_3->promote;
|
76 | 83 |
|
77 |
| -# node_1 rejoins node_3 |
| 84 | +# reconfigure node_1 as a standby following node_3 |
| 85 | +rmtree $node_1->data_dir; |
| 86 | +$node_1->init_from_backup($node_1, $backup_name); |
78 | 87 |
|
79 | 88 | my $node_3_connstr = $node_3->connstr;
|
80 |
| - |
81 |
| -unlink($node_2->data_dir . '/recovery.conf'); |
| 89 | +unlink($node_1->data_dir . '/recovery.conf'); |
82 | 90 | $node_1->append_conf('recovery.conf', qq(
|
83 | 91 | standby_mode=on
|
84 |
| -primary_conninfo='$node_3_connstr' |
| 92 | +primary_conninfo='$node_3_connstr application_name=node_1' |
85 | 93 | recovery_target_timeline='latest'
|
86 | 94 | ));
|
87 | 95 | $node_1->start();
|
88 | 96 |
|
89 |
| -# node_2 follows node_3 |
90 |
| - |
| 97 | +# also reconfigure node_2 to follow node_3 |
91 | 98 | unlink($node_2->data_dir . '/recovery.conf');
|
92 | 99 | $node_2->append_conf('recovery.conf', qq(
|
93 | 100 | standby_mode=on
|
94 |
| -primary_conninfo='$node_3_connstr' |
| 101 | +primary_conninfo='$node_3_connstr application_name=node_2' |
95 | 102 | recovery_target_timeline='latest'
|
96 | 103 | ));
|
97 | 104 | $node_2->restart();
|
98 | 105 |
|
99 |
| -# Promote node_1 |
| 106 | +# |
| 107 | +# Promote node_1, to create a split-brain scenario. |
| 108 | +# |
| 109 | + |
| 110 | +# make sure node_1 is full caught up with node_3 first |
| 111 | +$until_lsn = |
| 112 | + $node_3->safe_psql('postgres', "SELECT pg_current_xlog_location();"); |
| 113 | +$caughtup_query = |
| 114 | + "SELECT '$until_lsn'::pg_lsn <= pg_last_xlog_replay_location()"; |
| 115 | +$node_1->poll_query_until('postgres', $caughtup_query) |
| 116 | + or die "Timed out while waiting for standby to catch up"; |
100 | 117 |
|
101 | 118 | $node_1->promote;
|
102 | 119 |
|
103 | 120 | # Wait until nodes 1 and 3 have been fully promoted.
|
104 | 121 | $node_1->poll_query_until('postgres', "SELECT pg_is_in_recovery() <> true");
|
105 | 122 | $node_3->poll_query_until('postgres', "SELECT pg_is_in_recovery() <> true");
|
106 | 123 |
|
| 124 | +# |
107 | 125 | # We now have a split-brain with two primaries. Insert a row on both to
|
108 | 126 | # demonstratively create a split brain. After the rewind, we should only
|
109 | 127 | # see the insert on 1, as the insert on node 3 is rewound away.
|
| 128 | +# |
110 | 129 | $node_1->safe_psql('postgres', "INSERT INTO public.foo (t) VALUES ('keep this')");
|
111 | 130 |
|
112 | 131 | # Insert more rows in node 1, to bump up the XID counter. Otherwise, if
|
|
0 commit comments