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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy