Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 19890a0

Browse files
author
Amit Kapila
committed
Add option to enable two_phase commits via pg_create_logical_replication_slot.
Commit 0aa8a01 extends the output plugin API to allow decoding of prepared xacts and allowed the user to enable/disable the two-phase option via pg_logical_slot_get_changes(). This can lead to a problem such that the first time when it gets changes via pg_logical_slot_get_changes() without two_phase option enabled it will not get the prepared even though prepare is after consistent snapshot. Now next time during getting changes, if the two_phase option is enabled it can skip prepare because by that time start decoding point has been moved. So the user will only get commit prepared. Allow to enable/disable this option at the create slot time and default will be false. It will break the existing slots which is fine in a major release. Author: Ajin Cherian Reviewed-by: Amit Kapila and Vignesh C Discussion: https://postgr.es/m/d0f60d60-133d-bf8d-bd70-47784d8fabf3@enterprisedb.com
1 parent ee28cac commit 19890a0

File tree

20 files changed

+131
-93
lines changed

20 files changed

+131
-93
lines changed

contrib/test_decoding/expected/twophase.out

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
-- Test prepared transactions. When two-phase-commit is enabled, transactions are
22
-- decoded at PREPARE time rather than at COMMIT PREPARED time.
33
SET synchronous_commit = on;
4-
SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'test_decoding');
4+
SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'test_decoding', false, true);
55
?column?
66
----------
77
init
@@ -15,14 +15,14 @@ BEGIN;
1515
INSERT INTO test_prepared1 VALUES (1);
1616
INSERT INTO test_prepared1 VALUES (2);
1717
-- should show nothing because the xact has not been prepared yet.
18-
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'two-phase-commit', '1', 'include-xids', '0', 'skip-empty-xacts', '1');
18+
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');
1919
data
2020
------
2121
(0 rows)
2222

2323
PREPARE TRANSACTION 'test_prepared#1';
2424
-- should show both the above inserts and the PREPARE TRANSACTION.
25-
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'two-phase-commit', '1', 'include-xids', '0', 'skip-empty-xacts', '1');
25+
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');
2626
data
2727
----------------------------------------------------
2828
BEGIN
@@ -32,7 +32,7 @@ SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'two
3232
(4 rows)
3333

3434
COMMIT PREPARED 'test_prepared#1';
35-
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'two-phase-commit', '1', 'include-xids', '0', 'skip-empty-xacts', '1');
35+
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');
3636
data
3737
-----------------------------------
3838
COMMIT PREPARED 'test_prepared#1'
@@ -42,7 +42,7 @@ SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'two
4242
BEGIN;
4343
INSERT INTO test_prepared1 VALUES (3);
4444
PREPARE TRANSACTION 'test_prepared#2';
45-
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'two-phase-commit', '1', 'include-xids', '0', 'skip-empty-xacts', '1');
45+
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');
4646
data
4747
----------------------------------------------------
4848
BEGIN
@@ -51,7 +51,7 @@ SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'two
5151
(3 rows)
5252

5353
ROLLBACK PREPARED 'test_prepared#2';
54-
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'two-phase-commit', '1', 'include-xids', '0', 'skip-empty-xacts', '1');
54+
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');
5555
data
5656
-------------------------------------
5757
ROLLBACK PREPARED 'test_prepared#2'
@@ -74,7 +74,7 @@ WHERE locktype = 'relation'
7474
(2 rows)
7575

7676
-- The insert should show the newly altered column but not the DDL.
77-
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'two-phase-commit', '1', 'include-xids', '0', 'skip-empty-xacts', '1');
77+
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');
7878
data
7979
-------------------------------------------------------------------------
8080
BEGIN
@@ -89,7 +89,7 @@ SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'two
8989
-- the ALTER will stop us inserting into the other one.
9090
--
9191
INSERT INTO test_prepared2 VALUES (5);
92-
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'two-phase-commit', '1', 'include-xids', '0', 'skip-empty-xacts', '1');
92+
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');
9393
data
9494
----------------------------------------------------
9595
BEGIN
@@ -98,7 +98,7 @@ SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'two
9898
(3 rows)
9999

100100
COMMIT PREPARED 'test_prepared#3';
101-
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'two-phase-commit', '1', 'include-xids', '0', 'skip-empty-xacts', '1');
101+
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');
102102
data
103103
-----------------------------------
104104
COMMIT PREPARED 'test_prepared#3'
@@ -107,7 +107,7 @@ SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'two
107107
-- make sure stuff still works
108108
INSERT INTO test_prepared1 VALUES (6);
109109
INSERT INTO test_prepared2 VALUES (7);
110-
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'two-phase-commit', '1', 'include-xids', '0', 'skip-empty-xacts', '1');
110+
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');
111111
data
112112
--------------------------------------------------------------------
113113
BEGIN
@@ -138,7 +138,7 @@ WHERE locktype = 'relation'
138138

139139
-- The above CLUSTER command shouldn't cause a timeout on 2pc decoding.
140140
SET statement_timeout = '180s';
141-
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'two-phase-commit', '1', 'include-xids', '0', 'skip-empty-xacts', '1');
141+
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');
142142
data
143143
---------------------------------------------------------------------------
144144
BEGIN
@@ -150,7 +150,7 @@ SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'two
150150
RESET statement_timeout;
151151
COMMIT PREPARED 'test_prepared_lock';
152152
-- consume the commit
153-
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'two-phase-commit', '1', 'include-xids', '0', 'skip-empty-xacts', '1');
153+
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');
154154
data
155155
--------------------------------------
156156
COMMIT PREPARED 'test_prepared_lock'
@@ -166,7 +166,7 @@ INSERT INTO test_prepared_savepoint VALUES (2);
166166
ROLLBACK TO SAVEPOINT test_savepoint;
167167
PREPARE TRANSACTION 'test_prepared_savepoint';
168168
-- should show only 1, not 2
169-
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'two-phase-commit', '1', 'include-xids', '0', 'skip-empty-xacts', '1');
169+
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');
170170
data
171171
------------------------------------------------------------
172172
BEGIN
@@ -176,7 +176,7 @@ SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'two
176176

177177
COMMIT PREPARED 'test_prepared_savepoint';
178178
-- consume the commit
179-
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'two-phase-commit', '1', 'include-xids', '0', 'skip-empty-xacts', '1');
179+
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');
180180
data
181181
-------------------------------------------
182182
COMMIT PREPARED 'test_prepared_savepoint'
@@ -187,14 +187,14 @@ BEGIN;
187187
INSERT INTO test_prepared1 VALUES (20);
188188
PREPARE TRANSACTION 'test_prepared_nodecode';
189189
-- should show nothing
190-
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'two-phase-commit', '1', 'include-xids', '0', 'skip-empty-xacts', '1');
190+
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');
191191
data
192192
------
193193
(0 rows)
194194

195195
COMMIT PREPARED 'test_prepared_nodecode';
196196
-- should be decoded now
197-
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'two-phase-commit', '1', 'include-xids', '0', 'skip-empty-xacts', '1');
197+
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');
198198
data
199199
---------------------------------------------------------------------
200200
BEGIN
@@ -207,7 +207,7 @@ SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'two
207207
DROP TABLE test_prepared1;
208208
DROP TABLE test_prepared2;
209209
-- show results. There should be nothing to show
210-
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'two-phase-commit', '1', 'include-xids', '0', 'skip-empty-xacts', '1');
210+
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');
211211
data
212212
------
213213
(0 rows)

contrib/test_decoding/expected/twophase_snapshot.out

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ step s2txid: SELECT pg_current_xact_id() IS NULL;
66
?column?
77

88
f
9-
step s1init: SELECT 'init' FROM pg_create_logical_replication_slot('isolation_slot', 'test_decoding'); <waiting ...>
9+
step s1init: SELECT 'init' FROM pg_create_logical_replication_slot('isolation_slot', 'test_decoding', false, true); <waiting ...>
1010
step s3b: BEGIN;
1111
step s3txid: SELECT pg_current_xact_id() IS NULL;
1212
?column?
@@ -22,14 +22,14 @@ step s1init: <... completed>
2222

2323
init
2424
step s1insert: INSERT INTO do_write DEFAULT VALUES;
25-
step s1start: SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', 'false', 'skip-empty-xacts', '1', 'two-phase-commit', '1');
25+
step s1start: SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', 'false', 'skip-empty-xacts', '1');
2626
data
2727

2828
BEGIN
2929
table public.do_write: INSERT: id[integer]:2
3030
COMMIT
3131
step s2cp: COMMIT PREPARED 'test1';
32-
step s1start: SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', 'false', 'skip-empty-xacts', '1', 'two-phase-commit', '1');
32+
step s1start: SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', 'false', 'skip-empty-xacts', '1');
3333
data
3434

3535
BEGIN

contrib/test_decoding/expected/twophase_stream.out

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
-- Test streaming of two-phase commits
22
SET synchronous_commit = on;
3-
SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'test_decoding');
3+
SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'test_decoding', false, true);
44
?column?
55
----------
66
init
@@ -28,7 +28,7 @@ ROLLBACK TO s1;
2828
INSERT INTO stream_test SELECT repeat('a', 10) || g.i FROM generate_series(1, 20) g(i);
2929
PREPARE TRANSACTION 'test1';
3030
-- should show the inserts after a ROLLBACK
31-
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL,NULL, 'two-phase-commit', '1', 'include-xids', '0', 'skip-empty-xacts', '1', 'stream-changes', '1');
31+
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL,NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'stream-changes', '1');
3232
data
3333
----------------------------------------------------------
3434
streaming message: transactional: 1 prefix: test, sz: 50
@@ -59,7 +59,7 @@ SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL,NULL, 'two-
5959

6060
COMMIT PREPARED 'test1';
6161
--should show the COMMIT PREPARED and the other changes in the transaction
62-
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL,NULL, 'two-phase-commit', '1', 'include-xids', '0', 'skip-empty-xacts', '1', 'stream-changes', '1');
62+
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL,NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'stream-changes', '1');
6363
data
6464
-------------------------
6565
COMMIT PREPARED 'test1'
@@ -81,15 +81,15 @@ ROLLBACK to s1;
8181
INSERT INTO stream_test SELECT repeat('a', 10) || g.i FROM generate_series(1, 20) g(i);
8282
PREPARE TRANSACTION 'test1_nodecode';
8383
-- should NOT show inserts after a ROLLBACK
84-
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL,NULL, 'two-phase-commit', '1', 'include-xids', '0', 'skip-empty-xacts', '1', 'stream-changes', '1');
84+
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL,NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'stream-changes', '1');
8585
data
8686
----------------------------------------------------------
8787
streaming message: transactional: 1 prefix: test, sz: 50
8888
(1 row)
8989

9090
COMMIT PREPARED 'test1_nodecode';
9191
-- should show the inserts but not show a COMMIT PREPARED but a COMMIT
92-
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL,NULL, 'two-phase-commit', '1', 'include-xids', '0', 'skip-empty-xacts', '1', 'stream-changes', '1');
92+
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL,NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'stream-changes', '1');
9393
data
9494
-------------------------------------------------------------
9595
BEGIN

contrib/test_decoding/specs/twophase_snapshot.spec

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ teardown
1515
session "s1"
1616
setup { SET synchronous_commit=on; }
1717

18-
step "s1init" {SELECT 'init' FROM pg_create_logical_replication_slot('isolation_slot', 'test_decoding');}
19-
step "s1start" {SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', 'false', 'skip-empty-xacts', '1', 'two-phase-commit', '1');}
18+
step "s1init" {SELECT 'init' FROM pg_create_logical_replication_slot('isolation_slot', 'test_decoding', false, true);}
19+
step "s1start" {SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', 'false', 'skip-empty-xacts', '1');}
2020
step "s1insert" { INSERT INTO do_write DEFAULT VALUES; }
2121

2222
session "s2"

0 commit comments

Comments
 (0)