aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Paquier <michael@paquier.xyz>2021-12-14 10:58:33 +0900
committerMichael Paquier <michael@paquier.xyz>2021-12-14 10:58:33 +0900
commit65af1e842208cf3edec3b74842eec87b4a0138e5 (patch)
treee8cc0480b694dcb4ba63165ce5415d832939d2a5
parenta5fe66bfdaec7add9381b61b33f5c361eaacd055 (diff)
downloadpostgresql-65af1e842208cf3edec3b74842eec87b4a0138e5.tar.gz
postgresql-65af1e842208cf3edec3b74842eec87b4a0138e5.zip
Remove assertion for replication origins in PREPARE TRANSACTION
When using replication origins, pg_replication_origin_xact_setup() is an optional choice to be able to set a LSN and a timestamp to mark the origin, which would be additionally added to WAL for transaction commits or aborts (including 2PC transactions). An assertion in the code path of PREPARE TRANSACTION assumed that this data should always be set, so it would trigger when using replication origins without setting up an origin LSN. Some tests are added to cover more this kind of scenario. Oversight in commit 1eb6d65. Per discussion with Amit Kapila and Masahiko Sawada. Discussion: https://postgr.es/m/YbbBfNSvMm5nIINV@paquier.xyz Backpatch-through: 11
-rw-r--r--contrib/test_decoding/expected/replorigin.out76
-rw-r--r--contrib/test_decoding/sql/replorigin.sql32
-rw-r--r--src/backend/access/transam/twophase.c1
3 files changed, 108 insertions, 1 deletions
diff --git a/contrib/test_decoding/expected/replorigin.out b/contrib/test_decoding/expected/replorigin.out
index 3b249f4856f..01645a9174f 100644
--- a/contrib/test_decoding/expected/replorigin.out
+++ b/contrib/test_decoding/expected/replorigin.out
@@ -152,3 +152,79 @@ SELECT pg_replication_origin_drop('regress_test_decoding: regression_slot');
(1 row)
+-- Set of transactions with no origin LSNs and commit timestamps set for
+-- this session.
+SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot_no_lsn', 'test_decoding');
+ ?column?
+----------
+ init
+(1 row)
+
+SELECT pg_replication_origin_create('regress_test_decoding: regression_slot_no_lsn');
+ pg_replication_origin_create
+------------------------------
+ 1
+(1 row)
+
+-- mark session as replaying
+SELECT pg_replication_origin_session_setup('regress_test_decoding: regression_slot_no_lsn');
+ pg_replication_origin_session_setup
+-------------------------------------
+
+(1 row)
+
+-- Simple transactions
+BEGIN;
+INSERT INTO origin_tbl(data) VALUES ('no_lsn, commit');
+COMMIT;
+BEGIN;
+INSERT INTO origin_tbl(data) VALUES ('no_lsn, rollback');
+ROLLBACK;
+-- 2PC transactions
+BEGIN;
+INSERT INTO origin_tbl(data) VALUES ('no_lsn, commit prepared');
+PREPARE TRANSACTION 'replorigin_prepared';
+COMMIT PREPARED 'replorigin_prepared';
+BEGIN;
+INSERT INTO origin_tbl(data) VALUES ('no_lsn, rollback prepared');
+PREPARE TRANSACTION 'replorigin_prepared';
+ROLLBACK PREPARED 'replorigin_prepared';
+SELECT local_id, external_id,
+ remote_lsn <> '0/0' AS valid_remote_lsn,
+ local_lsn <> '0/0' AS valid_local_lsn
+ FROM pg_replication_origin_status;
+ local_id | external_id | valid_remote_lsn | valid_local_lsn
+----------+-----------------------------------------------+------------------+-----------------
+ 1 | regress_test_decoding: regression_slot_no_lsn | f | t
+(1 row)
+
+SELECT data FROM pg_logical_slot_get_changes('regression_slot_no_lsn', NULL, NULL, 'skip-empty-xacts', '1', 'include-xids', '0');
+ data
+-------------------------------------------------------------------------------------
+ BEGIN
+ table public.origin_tbl: INSERT: id[integer]:4 data[text]:'no_lsn, commit'
+ COMMIT
+ BEGIN
+ table public.origin_tbl: INSERT: id[integer]:6 data[text]:'no_lsn, commit prepared'
+ COMMIT
+(6 rows)
+
+-- Clean up
+SELECT pg_replication_origin_session_reset();
+ pg_replication_origin_session_reset
+-------------------------------------
+
+(1 row)
+
+SELECT pg_drop_replication_slot('regression_slot_no_lsn');
+ pg_drop_replication_slot
+--------------------------
+
+(1 row)
+
+SELECT pg_replication_origin_drop('regress_test_decoding: regression_slot_no_lsn');
+ pg_replication_origin_drop
+----------------------------
+
+(1 row)
+
diff --git a/contrib/test_decoding/sql/replorigin.sql b/contrib/test_decoding/sql/replorigin.sql
index 8979b306160..b854fbb247c 100644
--- a/contrib/test_decoding/sql/replorigin.sql
+++ b/contrib/test_decoding/sql/replorigin.sql
@@ -69,3 +69,35 @@ SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'inc
SELECT pg_drop_replication_slot('regression_slot');
SELECT pg_replication_origin_drop('regress_test_decoding: regression_slot');
+
+-- Set of transactions with no origin LSNs and commit timestamps set for
+-- this session.
+SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot_no_lsn', 'test_decoding');
+SELECT pg_replication_origin_create('regress_test_decoding: regression_slot_no_lsn');
+-- mark session as replaying
+SELECT pg_replication_origin_session_setup('regress_test_decoding: regression_slot_no_lsn');
+-- Simple transactions
+BEGIN;
+INSERT INTO origin_tbl(data) VALUES ('no_lsn, commit');
+COMMIT;
+BEGIN;
+INSERT INTO origin_tbl(data) VALUES ('no_lsn, rollback');
+ROLLBACK;
+-- 2PC transactions
+BEGIN;
+INSERT INTO origin_tbl(data) VALUES ('no_lsn, commit prepared');
+PREPARE TRANSACTION 'replorigin_prepared';
+COMMIT PREPARED 'replorigin_prepared';
+BEGIN;
+INSERT INTO origin_tbl(data) VALUES ('no_lsn, rollback prepared');
+PREPARE TRANSACTION 'replorigin_prepared';
+ROLLBACK PREPARED 'replorigin_prepared';
+SELECT local_id, external_id,
+ remote_lsn <> '0/0' AS valid_remote_lsn,
+ local_lsn <> '0/0' AS valid_local_lsn
+ FROM pg_replication_origin_status;
+SELECT data FROM pg_logical_slot_get_changes('regression_slot_no_lsn', NULL, NULL, 'skip-empty-xacts', '1', 'include-xids', '0');
+-- Clean up
+SELECT pg_replication_origin_session_reset();
+SELECT pg_drop_replication_slot('regression_slot_no_lsn');
+SELECT pg_replication_origin_drop('regress_test_decoding: regression_slot_no_lsn');
diff --git a/src/backend/access/transam/twophase.c b/src/backend/access/transam/twophase.c
index e727e55b330..6def1820caf 100644
--- a/src/backend/access/transam/twophase.c
+++ b/src/backend/access/transam/twophase.c
@@ -1151,7 +1151,6 @@ EndPrepare(GlobalTransaction gxact)
if (replorigin)
{
- Assert(replorigin_session_origin_lsn != InvalidXLogRecPtr);
hdr->origin_lsn = replorigin_session_origin_lsn;
hdr->origin_timestamp = replorigin_session_origin_timestamp;
}