Skip to content

Commit 4041537

Browse files
committed
tap testing
1 parent 6ba9acc commit 4041537

File tree

1 file changed

+225
-0
lines changed

1 file changed

+225
-0
lines changed

src/test/recovery/006_twophase.pl

Lines changed: 225 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,225 @@
1+
# Checks for recovery_min_apply_delay
2+
use strict;
3+
use warnings;
4+
use PostgresNode;
5+
use TestLib;
6+
use Test::More tests => 11;
7+
8+
sub PostgresNode::psql_ok {
9+
my ($self, $sql, $comment) = @_;
10+
11+
$self->command_ok(['psql', '-A', '-t', '--no-psqlrc',
12+
'-d', $self->connstr, '-c', $sql], $comment);
13+
}
14+
15+
sub PostgresNode::psql_fails {
16+
my ($self, $sql, $comment) = @_;
17+
18+
$self->command_ok(['psql', '-A', '-t', '--no-psqlrc',
19+
'-d', $self->connstr, '-c', $sql], $comment);
20+
}
21+
22+
# Setup master node
23+
my $node_master = get_new_node("Candie");
24+
$node_master->init(allows_streaming => 1);
25+
$node_master->append_conf('postgresql.conf', qq(
26+
max_prepared_transactions = 10
27+
));
28+
$node_master->start;
29+
$node_master->backup('master_backup');
30+
$node_master->psql('postgres', "create table t(id int)");
31+
32+
# Setup master node
33+
my $node_slave = get_new_node('Django');
34+
$node_slave->init_from_backup($node_master, 'master_backup', has_streaming => 1);
35+
$node_slave->start;
36+
37+
# Switch to synchronous replication
38+
$node_master->append_conf('postgresql.conf', qq(
39+
synchronous_standby_names = '*'
40+
));
41+
$node_master->restart;
42+
43+
###############################################################################
44+
# Check that we can commit and abort after soft restart.
45+
# Here checkpoint happens before shutdown and no WAL replay will not occur
46+
# during start. So code should re-create memory state from files.
47+
###############################################################################
48+
49+
$node_master->psql('postgres', "
50+
begin;
51+
insert into t values (42);
52+
prepare transaction 'x';
53+
begin;
54+
insert into t values (142);
55+
prepare transaction 'y';");
56+
$node_master->stop;
57+
$node_master->start;
58+
$node_master->psql_ok("commit prepared 'x'",
59+
'Commit prepared tx after restart.');
60+
$node_master->psql_ok("rollback prepared 'y'",
61+
'Rollback prepared tx after restart.');
62+
63+
###############################################################################
64+
# Check that we can commit and abort after hard restart.
65+
# On startup WAL replay will re-create memory for global transactions that
66+
# happend after last checkpoint and stored.
67+
###############################################################################
68+
69+
$node_master->psql('postgres', "
70+
begin;
71+
insert into t values (42);
72+
prepare transaction 'x';
73+
begin;
74+
insert into t values (142);
75+
prepare transaction 'y';");
76+
$node_master->teardown_node;
77+
$node_master->start;
78+
$node_master->psql_ok("commit prepared 'x'",
79+
'Commit prepared tx after teardown.');
80+
$node_master->psql_ok("rollback prepared 'y'",
81+
'Rollback prepared tx after teardown.');
82+
83+
###############################################################################
84+
# Check that we can replay several tx with same name.
85+
###############################################################################
86+
87+
$node_master->psql('postgres', "
88+
begin;
89+
insert into t values (42);
90+
prepare transaction 'x';
91+
commit prepared 'x';
92+
begin;
93+
insert into t values (42);
94+
prepare transaction 'x';");
95+
$node_master->teardown_node;
96+
$node_master->start;
97+
$node_master->psql_ok("commit prepared 'x'",
98+
'Check that we can replay several tx with same name.');
99+
100+
###############################################################################
101+
# Check that WAL replay will cleanup it's memory state and release locks while
102+
# replaying commit.
103+
###############################################################################
104+
105+
$node_master->psql('postgres', "
106+
begin;
107+
insert into t values (42);
108+
prepare transaction 'x';
109+
commit prepared 'x';");
110+
$node_master->teardown_node;
111+
$node_master->start;
112+
$node_master->psql_ok("
113+
begin;
114+
insert into t values (42);
115+
-- This prepare can fail due to 2pc identifier or locks conflicts if replay
116+
-- didn't cleanup proc, gxact and locks on commit.
117+
prepare transaction 'x';",
118+
"Check that WAL replay will cleanup it's memory state");
119+
120+
###############################################################################
121+
# Check that we can commit while running active sync slave and that there is no
122+
# active prepared transaction on slave after that.
123+
###############################################################################
124+
125+
$node_master->psql('postgres', "
126+
begin;
127+
insert into t values (42);
128+
prepare transaction 'x';
129+
commit prepared 'x';
130+
");
131+
my $result = $node_slave->psql('postgres', "select * from pg_prepared_xacts;");
132+
is($result, "", "Check that WAL replay will cleanup it's memory state on slave");
133+
134+
###############################################################################
135+
# The same as in previous case, but let's force checkpoint on slave between
136+
# prepare and commit.
137+
###############################################################################
138+
139+
$node_master->psql('postgres', "
140+
begin;
141+
insert into t values (42);
142+
prepare transaction 'x';
143+
");
144+
$node_slave->psql('postgres',"checkpoint;");
145+
$node_master->psql('postgres', "commit prepared 'x';");
146+
$result = $node_slave->psql('postgres', "select * from pg_prepared_xacts;");
147+
is($result, "", "Check that WAL replay will cleanup it's memory state on slave after checkpoint");
148+
149+
###############################################################################
150+
# Check that we can commit transaction on promoted slave.
151+
###############################################################################
152+
153+
$node_master->psql('postgres', "
154+
begin;
155+
insert into t values (42);
156+
prepare transaction 'x';
157+
");
158+
$node_master->teardown_node;
159+
$node_slave->promote;
160+
$node_slave->poll_query_until('postgres', "SELECT pg_is_in_recovery() <> true");
161+
$node_slave->psql_ok("commit prepared 'x';",
162+
"Check that we can commit transaction on promoted slave.");
163+
164+
# change roles
165+
($node_master, $node_slave) = ($node_slave, $node_master);
166+
$node_slave->enable_streaming($node_master);
167+
$node_slave->append_conf('recovery.conf', qq(
168+
recovery_target_timeline='latest'
169+
));
170+
$node_slave->start;
171+
172+
###############################################################################
173+
# Check that we restore prepared xacts after slave soft restart while master is
174+
# down.
175+
###############################################################################
176+
177+
$node_master->psql('postgres', "
178+
begin;
179+
insert into t values (42);
180+
prepare transaction 'x';
181+
");
182+
$node_master->stop;
183+
$node_slave->restart;
184+
$node_slave->promote;
185+
$node_slave->poll_query_until('postgres', "SELECT pg_is_in_recovery() <> true");
186+
my $prepared_count = $node_slave->psql('postgres',"select count(*) from pg_prepared_xacts");
187+
is($prepared_count, '1', "Check that we restore prepared xacts after slave soft restart while master is down.");
188+
189+
# restore state
190+
($node_master, $node_slave) = ($node_slave, $node_master);
191+
$node_slave->enable_streaming($node_master);
192+
$node_slave->append_conf('recovery.conf', qq(
193+
recovery_target_timeline='latest'
194+
));
195+
$node_slave->start;
196+
$node_master->psql('postgres',"commit prepared 'x'");
197+
198+
###############################################################################
199+
# Check that we restore prepared xacts after slave hard restart while master is
200+
# down.
201+
###############################################################################
202+
203+
$node_master->psql('postgres', "
204+
begin;
205+
insert into t values (242);
206+
prepare transaction 'x';
207+
");
208+
$node_master->stop;
209+
$node_slave->teardown_node;
210+
$node_slave->start;
211+
$node_slave->promote;
212+
$node_slave->poll_query_until('postgres', "SELECT pg_is_in_recovery() <> true");
213+
$prepared_count = $node_slave->psql('postgres',"select count(*) from pg_prepared_xacts");
214+
is($prepared_count, '1', "Check that we restore prepared xacts after slave hard restart while master is down.");
215+
216+
# restore state
217+
($node_master, $node_slave) = ($node_slave, $node_master);
218+
$node_slave->enable_streaming($node_master);
219+
$node_slave->append_conf('recovery.conf', qq(
220+
recovery_target_timeline='latest'
221+
));
222+
$node_slave->start;
223+
$node_master->psql('postgres',"commit prepared 'x'");
224+
225+

0 commit comments

Comments
 (0)