Skip to content

Commit 6969e24

Browse files
committed
Craig's version
1 parent 92c77ef commit 6969e24

File tree

3 files changed

+326
-81
lines changed

3 files changed

+326
-81
lines changed

contrib/test_decoding/expected/prepared.out

Lines changed: 199 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -6,103 +6,254 @@ SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'test_d
66
init
77
(1 row)
88

9-
CREATE TABLE test_prepared1(id int);
10-
CREATE TABLE test_prepared2(id int);
9+
SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot_2pc', 'test_decoding');
10+
?column?
11+
----------
12+
init
13+
(1 row)
14+
15+
CREATE TABLE test_prepared1(id integer primary key);
16+
CREATE TABLE test_prepared2(id integer primary key);
17+
-- Reused queries
18+
\set get_no2pc 'SELECT data FROM pg_logical_slot_get_changes(''regression_slot_2pc'', NULL, NULL, ''include-xids'', ''0'', ''skip-empty-xacts'', ''1'');'
19+
\set get_with2pc 'SELECT data FROM pg_logical_slot_get_changes(''regression_slot'', NULL, NULL, ''include-xids'', ''0'', ''skip-empty-xacts'', ''1'', ''twophase-decoding'', ''1'');'
20+
\set get_with2pc_nofilter 'SELECT data FROM pg_logical_slot_get_changes(''regression_slot'', NULL, NULL, ''include-xids'', ''0'', ''skip-empty-xacts'', ''1'', ''twophase-decoding'', ''1'', ''twophase-decode-with-catalog-changes'', ''1'');'
1121
-- test simple successful use of a prepared xact
1222
BEGIN;
1323
INSERT INTO test_prepared1 VALUES (1);
1424
PREPARE TRANSACTION 'test_prepared#1';
25+
:get_with2pc
26+
data
27+
----------------------------------------------------
28+
BEGIN
29+
table public.test_prepared1: INSERT: id[integer]:1
30+
PREPARE TRANSACTION 'test_prepared#1'
31+
(3 rows)
32+
33+
:get_no2pc
34+
data
35+
------
36+
(0 rows)
37+
1538
COMMIT PREPARED 'test_prepared#1';
39+
:get_with2pc
40+
data
41+
------
42+
(0 rows)
43+
44+
:get_no2pc
45+
data
46+
----------------------------------------------------
47+
BEGIN
48+
table public.test_prepared1: INSERT: id[integer]:1
49+
COMMIT
50+
(3 rows)
51+
1652
INSERT INTO test_prepared1 VALUES (2);
1753
-- test abort of a prepared xact
1854
BEGIN;
1955
INSERT INTO test_prepared1 VALUES (3);
2056
PREPARE TRANSACTION 'test_prepared#2';
57+
:get_no2pc
58+
data
59+
----------------------------------------------------
60+
BEGIN
61+
table public.test_prepared1: INSERT: id[integer]:2
62+
COMMIT
63+
(3 rows)
64+
65+
:get_with2pc
66+
data
67+
----------------------------------------------------
68+
BEGIN
69+
table public.test_prepared1: INSERT: id[integer]:2
70+
COMMIT
71+
BEGIN
72+
table public.test_prepared1: INSERT: id[integer]:3
73+
PREPARE TRANSACTION 'test_prepared#2'
74+
(6 rows)
75+
2176
ROLLBACK PREPARED 'test_prepared#2';
77+
:get_no2pc
78+
data
79+
------
80+
(0 rows)
81+
82+
:get_with2pc
83+
data
84+
------
85+
(0 rows)
86+
2287
INSERT INTO test_prepared1 VALUES (4);
2388
-- test prepared xact containing ddl
2489
BEGIN;
2590
INSERT INTO test_prepared1 VALUES (5);
2691
ALTER TABLE test_prepared1 ADD COLUMN data text;
2792
INSERT INTO test_prepared1 VALUES (6, 'frakbar');
2893
PREPARE TRANSACTION 'test_prepared#3';
29-
-- test that we decode correctly while an uncommitted prepared xact
30-
-- with ddl exists.
31-
-- separate table because of the lock from the ALTER
32-
-- this will come before the '5' row above, as this commits before it.
33-
INSERT INTO test_prepared2 VALUES (7);
34-
COMMIT PREPARED 'test_prepared#3';
35-
-- make sure stuff still works
36-
INSERT INTO test_prepared1 VALUES (8);
37-
INSERT INTO test_prepared2 VALUES (9);
38-
-- cleanup
39-
DROP TABLE test_prepared1;
40-
DROP TABLE test_prepared2;
41-
-- show results
42-
SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');
43-
data
44-
-------------------------------------------------------------------------
94+
SELECT 'test_prepared_1' AS relation, locktype, mode
95+
FROM pg_locks
96+
WHERE locktype = 'relation'
97+
AND relation = 'test_prepared1'::regclass;
98+
relation | locktype | mode
99+
-----------------+----------+---------------------
100+
test_prepared_1 | relation | RowExclusiveLock
101+
test_prepared_1 | relation | AccessExclusiveLock
102+
(2 rows)
103+
104+
:get_no2pc
105+
data
106+
----------------------------------------------------
45107
BEGIN
46-
table public.test_prepared1: INSERT: id[integer]:1
108+
table public.test_prepared1: INSERT: id[integer]:4
47109
COMMIT
110+
(3 rows)
111+
112+
:get_with2pc
113+
data
114+
----------------------------------------------------
48115
BEGIN
49-
table public.test_prepared1: INSERT: id[integer]:2
116+
table public.test_prepared1: INSERT: id[integer]:4
50117
COMMIT
118+
(3 rows)
119+
120+
-- Test that we decode correctly while an uncommitted prepared xact
121+
-- with ddl exists. Our 2pc filter callback will skip decoding of xacts
122+
-- with catalog changes at PREPARE time, so we don't decode it now.
123+
--
124+
-- Use a separate table for the concurrent transaction because the lock from
125+
-- the ALTER will stop us inserting into the other one.
126+
--
127+
-- We should see '7' before '5' in our results since it commits first.
128+
--
129+
INSERT INTO test_prepared2 VALUES (7);
130+
:get_with2pc
131+
data
132+
----------------------------------------------------
51133
BEGIN
52-
table public.test_prepared1: INSERT: id[integer]:4
134+
table public.test_prepared2: INSERT: id[integer]:7
53135
COMMIT
136+
(3 rows)
137+
138+
:get_no2pc
139+
data
140+
----------------------------------------------------
54141
BEGIN
55142
table public.test_prepared2: INSERT: id[integer]:7
56143
COMMIT
144+
(3 rows)
145+
146+
COMMIT PREPARED 'test_prepared#3';
147+
:get_no2pc
148+
data
149+
-------------------------------------------------------------------------
57150
BEGIN
58151
table public.test_prepared1: INSERT: id[integer]:5
59152
table public.test_prepared1: INSERT: id[integer]:6 data[text]:'frakbar'
60153
COMMIT
61-
BEGIN
62-
table public.test_prepared1: INSERT: id[integer]:8 data[text]:null
63-
COMMIT
64-
BEGIN
65-
table public.test_prepared2: INSERT: id[integer]:9
66-
COMMIT
67-
(22 rows)
154+
(4 rows)
68155

69-
-- same but with twophase decoding
70-
SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'twophase-decoding', '1');
156+
:get_with2pc
71157
data
72158
-------------------------------------------------------------------------
73-
BEGIN
74-
table public.test_prepared1: INSERT: id[integer]:1
75-
PREPARE 'test_prepared#1'
76-
COMMIT PREPARED 'test_prepared#1'
77-
BEGIN
78-
table public.test_prepared1: INSERT: id[integer]:2
79-
COMMIT
80-
BEGIN
81-
table public.test_prepared1: INSERT: id[integer]:3
82-
PREPARE 'test_prepared#2'
83-
ABORT PREPARED 'test_prepared#2'
84-
BEGIN
85-
table public.test_prepared1: INSERT: id[integer]:4
86-
COMMIT
87159
BEGIN
88160
table public.test_prepared1: INSERT: id[integer]:5
89161
table public.test_prepared1: INSERT: id[integer]:6 data[text]:'frakbar'
90-
PREPARE 'test_prepared#3'
162+
PREPARE TRANSACTION 'test_prepared#3';
163+
COMMIT PREPARED 'test_prepared#3';
164+
(5 rows)
165+
166+
-- make sure stuff still works
167+
INSERT INTO test_prepared1 VALUES (8);
168+
INSERT INTO test_prepared2 VALUES (9);
169+
:get_with2pc
170+
data
171+
--------------------------------------------------------------------
91172
BEGIN
92-
table public.test_prepared2: INSERT: id[integer]:7
173+
table public.test_prepared1: INSERT: id[integer]:8 data[text]:null
174+
COMMIT
175+
BEGIN
176+
table public.test_prepared2: INSERT: id[integer]:9
93177
COMMIT
94-
COMMIT PREPARED 'test_prepared#3'
178+
(6 rows)
179+
180+
:get_no2pc
181+
data
182+
--------------------------------------------------------------------
95183
BEGIN
96184
table public.test_prepared1: INSERT: id[integer]:8 data[text]:null
97185
COMMIT
98186
BEGIN
99187
table public.test_prepared2: INSERT: id[integer]:9
100188
COMMIT
101-
(28 rows)
189+
(6 rows)
102190

191+
-- If we do something that takes a strong lock on a catalog relation we need to
192+
-- read in order to decode a transaction we deadlock; we can't finish decoding
193+
-- until the lock is released, but we're waiting for decoding to finish so we
194+
-- can make a commit/abort decision.
195+
---
196+
BEGIN;
197+
INSERT INTO test_prepared1 VALUES (10, 'othercol');
198+
CLUSTER test_prepared1 USING test_prepared1_pkey;
199+
INSERT INTO test_prepared1 VALUES (11, 'othercol2');
200+
PREPARE TRANSACTION 'test_prepared_lock';
201+
SELECT 'pg_class' AS relation, locktype, mode
202+
FROM pg_locks
203+
WHERE locktype = 'relation'
204+
AND relation = 'pg_class'::regclass;
205+
relation | locktype | mode
206+
----------+----------+------
207+
(0 rows)
208+
209+
-- Shouldn't see anything with 2pc decoding off
210+
:get_no2pc
211+
data
212+
------
213+
(0 rows)
214+
215+
-- If we try to decode it now we'll deadlock
216+
SET statement_timeout = '10s';
217+
:get_with2pc_nofilter
218+
-- FIXME we expect a timeout here, but it actually works...
219+
ERROR: statement timed out
220+
221+
RESET statement_timeout;
222+
-- we can decode past it by skipping xacts with catalog changes
223+
-- and let it be decoded after COMMIT PREPARED, though.
224+
:get_with2pc
225+
data
226+
------
227+
(0 rows)
228+
229+
COMMIT PREPARED 'test_prepared_lock';
230+
-- Both will work normally after we commit
231+
:get_no2pc
232+
data
233+
----------------------------------------------------------------------------
234+
BEGIN
235+
table public.test_prepared1: INSERT: id[integer]:10 data[text]:'othercol'
236+
table public.test_prepared1: INSERT: id[integer]:11 data[text]:'othercol2'
237+
COMMIT
238+
(4 rows)
239+
240+
:get_with2pc
241+
data
242+
------
243+
(0 rows)
244+
245+
-- cleanup
246+
DROP TABLE test_prepared1;
247+
DROP TABLE test_prepared2;
103248
SELECT pg_drop_replication_slot('regression_slot');
104249
pg_drop_replication_slot
105250
--------------------------
106251

107252
(1 row)
108253

254+
SELECT pg_drop_replication_slot('regression_slot_2pc');
255+
pg_drop_replication_slot
256+
--------------------------
257+
258+
(1 row)
259+

0 commit comments

Comments
 (0)