mirror of
https://github.com/postgres/postgres.git
synced 2025-07-27 12:41:57 +03:00
Add option to enable two_phase commits via pg_create_logical_replication_slot.
Commit 0aa8a01d04
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
This commit is contained in:
@ -1,7 +1,7 @@
|
||||
-- Test prepared transactions. When two-phase-commit is enabled, transactions are
|
||||
-- decoded at PREPARE time rather than at COMMIT PREPARED time.
|
||||
SET synchronous_commit = on;
|
||||
SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'test_decoding');
|
||||
SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'test_decoding', false, true);
|
||||
?column?
|
||||
----------
|
||||
init
|
||||
@ -15,14 +15,14 @@ BEGIN;
|
||||
INSERT INTO test_prepared1 VALUES (1);
|
||||
INSERT INTO test_prepared1 VALUES (2);
|
||||
-- should show nothing because the xact has not been prepared yet.
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'two-phase-commit', '1', 'include-xids', '0', 'skip-empty-xacts', '1');
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');
|
||||
data
|
||||
------
|
||||
(0 rows)
|
||||
|
||||
PREPARE TRANSACTION 'test_prepared#1';
|
||||
-- should show both the above inserts and the PREPARE TRANSACTION.
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'two-phase-commit', '1', 'include-xids', '0', 'skip-empty-xacts', '1');
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');
|
||||
data
|
||||
----------------------------------------------------
|
||||
BEGIN
|
||||
@ -32,7 +32,7 @@ SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'two
|
||||
(4 rows)
|
||||
|
||||
COMMIT PREPARED 'test_prepared#1';
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'two-phase-commit', '1', 'include-xids', '0', 'skip-empty-xacts', '1');
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');
|
||||
data
|
||||
-----------------------------------
|
||||
COMMIT PREPARED 'test_prepared#1'
|
||||
@ -42,7 +42,7 @@ SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'two
|
||||
BEGIN;
|
||||
INSERT INTO test_prepared1 VALUES (3);
|
||||
PREPARE TRANSACTION 'test_prepared#2';
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'two-phase-commit', '1', 'include-xids', '0', 'skip-empty-xacts', '1');
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');
|
||||
data
|
||||
----------------------------------------------------
|
||||
BEGIN
|
||||
@ -51,7 +51,7 @@ SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'two
|
||||
(3 rows)
|
||||
|
||||
ROLLBACK PREPARED 'test_prepared#2';
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'two-phase-commit', '1', 'include-xids', '0', 'skip-empty-xacts', '1');
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');
|
||||
data
|
||||
-------------------------------------
|
||||
ROLLBACK PREPARED 'test_prepared#2'
|
||||
@ -74,7 +74,7 @@ WHERE locktype = 'relation'
|
||||
(2 rows)
|
||||
|
||||
-- The insert should show the newly altered column but not the DDL.
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'two-phase-commit', '1', 'include-xids', '0', 'skip-empty-xacts', '1');
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');
|
||||
data
|
||||
-------------------------------------------------------------------------
|
||||
BEGIN
|
||||
@ -89,7 +89,7 @@ SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'two
|
||||
-- the ALTER will stop us inserting into the other one.
|
||||
--
|
||||
INSERT INTO test_prepared2 VALUES (5);
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'two-phase-commit', '1', 'include-xids', '0', 'skip-empty-xacts', '1');
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');
|
||||
data
|
||||
----------------------------------------------------
|
||||
BEGIN
|
||||
@ -98,7 +98,7 @@ SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'two
|
||||
(3 rows)
|
||||
|
||||
COMMIT PREPARED 'test_prepared#3';
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'two-phase-commit', '1', 'include-xids', '0', 'skip-empty-xacts', '1');
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');
|
||||
data
|
||||
-----------------------------------
|
||||
COMMIT PREPARED 'test_prepared#3'
|
||||
@ -107,7 +107,7 @@ SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'two
|
||||
-- make sure stuff still works
|
||||
INSERT INTO test_prepared1 VALUES (6);
|
||||
INSERT INTO test_prepared2 VALUES (7);
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'two-phase-commit', '1', 'include-xids', '0', 'skip-empty-xacts', '1');
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');
|
||||
data
|
||||
--------------------------------------------------------------------
|
||||
BEGIN
|
||||
@ -138,7 +138,7 @@ WHERE locktype = 'relation'
|
||||
|
||||
-- The above CLUSTER command shouldn't cause a timeout on 2pc decoding.
|
||||
SET statement_timeout = '180s';
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'two-phase-commit', '1', 'include-xids', '0', 'skip-empty-xacts', '1');
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');
|
||||
data
|
||||
---------------------------------------------------------------------------
|
||||
BEGIN
|
||||
@ -150,7 +150,7 @@ SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'two
|
||||
RESET statement_timeout;
|
||||
COMMIT PREPARED 'test_prepared_lock';
|
||||
-- consume the commit
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'two-phase-commit', '1', 'include-xids', '0', 'skip-empty-xacts', '1');
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');
|
||||
data
|
||||
--------------------------------------
|
||||
COMMIT PREPARED 'test_prepared_lock'
|
||||
@ -166,7 +166,7 @@ INSERT INTO test_prepared_savepoint VALUES (2);
|
||||
ROLLBACK TO SAVEPOINT test_savepoint;
|
||||
PREPARE TRANSACTION 'test_prepared_savepoint';
|
||||
-- should show only 1, not 2
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'two-phase-commit', '1', 'include-xids', '0', 'skip-empty-xacts', '1');
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');
|
||||
data
|
||||
------------------------------------------------------------
|
||||
BEGIN
|
||||
@ -176,7 +176,7 @@ SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'two
|
||||
|
||||
COMMIT PREPARED 'test_prepared_savepoint';
|
||||
-- consume the commit
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'two-phase-commit', '1', 'include-xids', '0', 'skip-empty-xacts', '1');
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');
|
||||
data
|
||||
-------------------------------------------
|
||||
COMMIT PREPARED 'test_prepared_savepoint'
|
||||
@ -187,14 +187,14 @@ BEGIN;
|
||||
INSERT INTO test_prepared1 VALUES (20);
|
||||
PREPARE TRANSACTION 'test_prepared_nodecode';
|
||||
-- should show nothing
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'two-phase-commit', '1', 'include-xids', '0', 'skip-empty-xacts', '1');
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');
|
||||
data
|
||||
------
|
||||
(0 rows)
|
||||
|
||||
COMMIT PREPARED 'test_prepared_nodecode';
|
||||
-- should be decoded now
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'two-phase-commit', '1', 'include-xids', '0', 'skip-empty-xacts', '1');
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');
|
||||
data
|
||||
---------------------------------------------------------------------
|
||||
BEGIN
|
||||
@ -207,7 +207,7 @@ SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'two
|
||||
DROP TABLE test_prepared1;
|
||||
DROP TABLE test_prepared2;
|
||||
-- show results. There should be nothing to show
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'two-phase-commit', '1', 'include-xids', '0', 'skip-empty-xacts', '1');
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');
|
||||
data
|
||||
------
|
||||
(0 rows)
|
||||
|
@ -6,7 +6,7 @@ step s2txid: SELECT pg_current_xact_id() IS NULL;
|
||||
?column?
|
||||
|
||||
f
|
||||
step s1init: SELECT 'init' FROM pg_create_logical_replication_slot('isolation_slot', 'test_decoding'); <waiting ...>
|
||||
step s1init: SELECT 'init' FROM pg_create_logical_replication_slot('isolation_slot', 'test_decoding', false, true); <waiting ...>
|
||||
step s3b: BEGIN;
|
||||
step s3txid: SELECT pg_current_xact_id() IS NULL;
|
||||
?column?
|
||||
@ -22,14 +22,14 @@ step s1init: <... completed>
|
||||
|
||||
init
|
||||
step s1insert: INSERT INTO do_write DEFAULT VALUES;
|
||||
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');
|
||||
step s1start: SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', 'false', 'skip-empty-xacts', '1');
|
||||
data
|
||||
|
||||
BEGIN
|
||||
table public.do_write: INSERT: id[integer]:2
|
||||
COMMIT
|
||||
step s2cp: COMMIT PREPARED 'test1';
|
||||
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');
|
||||
step s1start: SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', 'false', 'skip-empty-xacts', '1');
|
||||
data
|
||||
|
||||
BEGIN
|
||||
|
@ -1,6 +1,6 @@
|
||||
-- Test streaming of two-phase commits
|
||||
SET synchronous_commit = on;
|
||||
SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'test_decoding');
|
||||
SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'test_decoding', false, true);
|
||||
?column?
|
||||
----------
|
||||
init
|
||||
@ -28,7 +28,7 @@ ROLLBACK TO s1;
|
||||
INSERT INTO stream_test SELECT repeat('a', 10) || g.i FROM generate_series(1, 20) g(i);
|
||||
PREPARE TRANSACTION 'test1';
|
||||
-- should show the inserts after a ROLLBACK
|
||||
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');
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL,NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'stream-changes', '1');
|
||||
data
|
||||
----------------------------------------------------------
|
||||
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-
|
||||
|
||||
COMMIT PREPARED 'test1';
|
||||
--should show the COMMIT PREPARED and the other changes in the transaction
|
||||
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');
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL,NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'stream-changes', '1');
|
||||
data
|
||||
-------------------------
|
||||
COMMIT PREPARED 'test1'
|
||||
@ -81,7 +81,7 @@ ROLLBACK to s1;
|
||||
INSERT INTO stream_test SELECT repeat('a', 10) || g.i FROM generate_series(1, 20) g(i);
|
||||
PREPARE TRANSACTION 'test1_nodecode';
|
||||
-- should NOT show inserts after a ROLLBACK
|
||||
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');
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL,NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'stream-changes', '1');
|
||||
data
|
||||
----------------------------------------------------------
|
||||
streaming message: transactional: 1 prefix: test, sz: 50
|
||||
@ -89,7 +89,7 @@ SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL,NULL, 'two-
|
||||
|
||||
COMMIT PREPARED 'test1_nodecode';
|
||||
-- should show the inserts but not show a COMMIT PREPARED but a COMMIT
|
||||
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');
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL,NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'stream-changes', '1');
|
||||
data
|
||||
-------------------------------------------------------------
|
||||
BEGIN
|
||||
|
@ -15,8 +15,8 @@ teardown
|
||||
session "s1"
|
||||
setup { SET synchronous_commit=on; }
|
||||
|
||||
step "s1init" {SELECT 'init' FROM pg_create_logical_replication_slot('isolation_slot', 'test_decoding');}
|
||||
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');}
|
||||
step "s1init" {SELECT 'init' FROM pg_create_logical_replication_slot('isolation_slot', 'test_decoding', false, true);}
|
||||
step "s1start" {SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', 'false', 'skip-empty-xacts', '1');}
|
||||
step "s1insert" { INSERT INTO do_write DEFAULT VALUES; }
|
||||
|
||||
session "s2"
|
||||
|
@ -1,7 +1,7 @@
|
||||
-- Test prepared transactions. When two-phase-commit is enabled, transactions are
|
||||
-- decoded at PREPARE time rather than at COMMIT PREPARED time.
|
||||
SET synchronous_commit = on;
|
||||
SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'test_decoding');
|
||||
SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'test_decoding', false, true);
|
||||
|
||||
CREATE TABLE test_prepared1(id integer primary key);
|
||||
CREATE TABLE test_prepared2(id integer primary key);
|
||||
@ -12,20 +12,20 @@ BEGIN;
|
||||
INSERT INTO test_prepared1 VALUES (1);
|
||||
INSERT INTO test_prepared1 VALUES (2);
|
||||
-- should show nothing because the xact has not been prepared yet.
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'two-phase-commit', '1', 'include-xids', '0', 'skip-empty-xacts', '1');
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');
|
||||
PREPARE TRANSACTION 'test_prepared#1';
|
||||
-- should show both the above inserts and the PREPARE TRANSACTION.
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'two-phase-commit', '1', 'include-xids', '0', 'skip-empty-xacts', '1');
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');
|
||||
COMMIT PREPARED 'test_prepared#1';
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'two-phase-commit', '1', 'include-xids', '0', 'skip-empty-xacts', '1');
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');
|
||||
|
||||
-- Test that rollback of a prepared xact is decoded.
|
||||
BEGIN;
|
||||
INSERT INTO test_prepared1 VALUES (3);
|
||||
PREPARE TRANSACTION 'test_prepared#2';
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'two-phase-commit', '1', 'include-xids', '0', 'skip-empty-xacts', '1');
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');
|
||||
ROLLBACK PREPARED 'test_prepared#2';
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'two-phase-commit', '1', 'include-xids', '0', 'skip-empty-xacts', '1');
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');
|
||||
|
||||
-- Test prepare of a xact containing ddl. Leaving xact uncommitted for next test.
|
||||
BEGIN;
|
||||
@ -38,7 +38,7 @@ FROM pg_locks
|
||||
WHERE locktype = 'relation'
|
||||
AND relation = 'test_prepared1'::regclass;
|
||||
-- The insert should show the newly altered column but not the DDL.
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'two-phase-commit', '1', 'include-xids', '0', 'skip-empty-xacts', '1');
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');
|
||||
|
||||
-- Test that we decode correctly while an uncommitted prepared xact
|
||||
-- with ddl exists.
|
||||
@ -47,14 +47,14 @@ SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'two
|
||||
-- the ALTER will stop us inserting into the other one.
|
||||
--
|
||||
INSERT INTO test_prepared2 VALUES (5);
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'two-phase-commit', '1', 'include-xids', '0', 'skip-empty-xacts', '1');
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');
|
||||
|
||||
COMMIT PREPARED 'test_prepared#3';
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'two-phase-commit', '1', 'include-xids', '0', 'skip-empty-xacts', '1');
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');
|
||||
-- make sure stuff still works
|
||||
INSERT INTO test_prepared1 VALUES (6);
|
||||
INSERT INTO test_prepared2 VALUES (7);
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'two-phase-commit', '1', 'include-xids', '0', 'skip-empty-xacts', '1');
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');
|
||||
|
||||
-- Check 'CLUSTER' (as operation that hold exclusive lock) doesn't block
|
||||
-- logical decoding.
|
||||
@ -70,11 +70,11 @@ WHERE locktype = 'relation'
|
||||
AND relation = 'test_prepared1'::regclass;
|
||||
-- The above CLUSTER command shouldn't cause a timeout on 2pc decoding.
|
||||
SET statement_timeout = '180s';
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'two-phase-commit', '1', 'include-xids', '0', 'skip-empty-xacts', '1');
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');
|
||||
RESET statement_timeout;
|
||||
COMMIT PREPARED 'test_prepared_lock';
|
||||
-- consume the commit
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'two-phase-commit', '1', 'include-xids', '0', 'skip-empty-xacts', '1');
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');
|
||||
|
||||
-- Test savepoints and sub-xacts. Creating savepoints will create
|
||||
-- sub-xacts implicitly.
|
||||
@ -86,26 +86,26 @@ INSERT INTO test_prepared_savepoint VALUES (2);
|
||||
ROLLBACK TO SAVEPOINT test_savepoint;
|
||||
PREPARE TRANSACTION 'test_prepared_savepoint';
|
||||
-- should show only 1, not 2
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'two-phase-commit', '1', 'include-xids', '0', 'skip-empty-xacts', '1');
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');
|
||||
COMMIT PREPARED 'test_prepared_savepoint';
|
||||
-- consume the commit
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'two-phase-commit', '1', 'include-xids', '0', 'skip-empty-xacts', '1');
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');
|
||||
|
||||
-- Test that a GID containing "_nodecode" gets decoded at commit prepared time.
|
||||
BEGIN;
|
||||
INSERT INTO test_prepared1 VALUES (20);
|
||||
PREPARE TRANSACTION 'test_prepared_nodecode';
|
||||
-- should show nothing
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'two-phase-commit', '1', 'include-xids', '0', 'skip-empty-xacts', '1');
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');
|
||||
COMMIT PREPARED 'test_prepared_nodecode';
|
||||
-- should be decoded now
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'two-phase-commit', '1', 'include-xids', '0', 'skip-empty-xacts', '1');
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');
|
||||
|
||||
-- Test 8:
|
||||
-- cleanup and make sure results are also empty
|
||||
DROP TABLE test_prepared1;
|
||||
DROP TABLE test_prepared2;
|
||||
-- show results. There should be nothing to show
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'two-phase-commit', '1', 'include-xids', '0', 'skip-empty-xacts', '1');
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');
|
||||
|
||||
SELECT pg_drop_replication_slot('regression_slot');
|
||||
|
@ -1,7 +1,7 @@
|
||||
-- Test streaming of two-phase commits
|
||||
|
||||
SET synchronous_commit = on;
|
||||
SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'test_decoding');
|
||||
SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'test_decoding', false, true);
|
||||
|
||||
CREATE TABLE stream_test(data text);
|
||||
|
||||
@ -18,11 +18,11 @@ ROLLBACK TO s1;
|
||||
INSERT INTO stream_test SELECT repeat('a', 10) || g.i FROM generate_series(1, 20) g(i);
|
||||
PREPARE TRANSACTION 'test1';
|
||||
-- should show the inserts after a ROLLBACK
|
||||
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');
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL,NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'stream-changes', '1');
|
||||
|
||||
COMMIT PREPARED 'test1';
|
||||
--should show the COMMIT PREPARED and the other changes in the transaction
|
||||
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');
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL,NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'stream-changes', '1');
|
||||
|
||||
-- streaming test with sub-transaction and PREPARE/COMMIT PREPARED but with
|
||||
-- filtered gid. gids with '_nodecode' will not be decoded at prepare time.
|
||||
@ -35,11 +35,11 @@ ROLLBACK to s1;
|
||||
INSERT INTO stream_test SELECT repeat('a', 10) || g.i FROM generate_series(1, 20) g(i);
|
||||
PREPARE TRANSACTION 'test1_nodecode';
|
||||
-- should NOT show inserts after a ROLLBACK
|
||||
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');
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL,NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'stream-changes', '1');
|
||||
|
||||
COMMIT PREPARED 'test1_nodecode';
|
||||
-- should show the inserts but not show a COMMIT PREPARED but a COMMIT
|
||||
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');
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL,NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'stream-changes', '1');
|
||||
|
||||
DROP TABLE stream_test;
|
||||
SELECT pg_drop_replication_slot('regression_slot');
|
||||
|
@ -164,7 +164,6 @@ pg_decode_startup(LogicalDecodingContext *ctx, OutputPluginOptions *opt,
|
||||
ListCell *option;
|
||||
TestDecodingData *data;
|
||||
bool enable_streaming = false;
|
||||
bool enable_twophase = false;
|
||||
|
||||
data = palloc0(sizeof(TestDecodingData));
|
||||
data->context = AllocSetContextCreate(ctx->context,
|
||||
@ -265,16 +264,6 @@ pg_decode_startup(LogicalDecodingContext *ctx, OutputPluginOptions *opt,
|
||||
errmsg("could not parse value \"%s\" for parameter \"%s\"",
|
||||
strVal(elem->arg), elem->defname)));
|
||||
}
|
||||
else if (strcmp(elem->defname, "two-phase-commit") == 0)
|
||||
{
|
||||
if (elem->arg == NULL)
|
||||
continue;
|
||||
else if (!parse_bool(strVal(elem->arg), &enable_twophase))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||
errmsg("could not parse value \"%s\" for parameter \"%s\"",
|
||||
strVal(elem->arg), elem->defname)));
|
||||
}
|
||||
else
|
||||
{
|
||||
ereport(ERROR,
|
||||
@ -286,7 +275,6 @@ pg_decode_startup(LogicalDecodingContext *ctx, OutputPluginOptions *opt,
|
||||
}
|
||||
|
||||
ctx->streaming &= enable_streaming;
|
||||
ctx->twophase &= enable_twophase;
|
||||
}
|
||||
|
||||
/* cleanup this plugin's resources */
|
||||
|
Reference in New Issue
Block a user