mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-08-25 03:27:19 +02:00
The snapshot assembly during the creation of logical slots relied waiting for transactions in xl_running_xacts to end, by checking for their commit/abort records. Unfortunately, despite locking, it is possible to see an xl_running_xact record listing transactions as ready, that have already WAL-logged an commit/abort record, as the locking just prevents the ProcArray to be adjusted, and the commit record has to be logged first. That lead to either delayed or hanging snapshot creation, because snapbuild.c would wait "forever" to see commit/abort records for some transactions. That hang resolved only if a xl_running_xacts record without any running transactions happened to be logged, far from certain on a busy server. It's impractical to prevent that via more heavyweight locking, the likelihood of deadlocks and significantly increased contention would be too big. Instead change the initial snapshot creation to be solely based on tracking the oldest running transaction via xl_running_xacts->oldestRunningXid - that actually ends up significantly simplifying the code. That has two disadvantages: 1) Because we cannot fully "trust" the contents of xl_running_xacts, we cannot use it to build the initial snapshot. Instead we have to wait twice for all running transactions to finish. 2) Previously a slot, unless the race occurred, could be created when the all transaction perceived as running based on commit/abort records, now we have to wait for the next xl_running_xacts record. To address that, trigger logging new xl_running_xacts record from within snapbuild.c exactly when necessary. Unfortunately snabuild.c's SnapBuild is stored on disk, one of the stupider ideas of a certain Mr Freund, so we can't change it in a minor release. As this is going to be backpatched, we have to hack around a bit to keep on-disk compatibility. A later commit will rejigger that on master. Author: Andres Freund, based on a quite different patch from Petr Jelinek Analyzed-By: Petr Jelinek Reviewed-By: Petr Jelinek Discussion: https://postgr.es/m/f37e975c-908f-858e-707f-058d3b1eb214@2ndquadrant.com Backpatch: 9.4-, where logical decoding has been introduced
53 lines
1.6 KiB
Plaintext
53 lines
1.6 KiB
Plaintext
Parsed test spec with 3 sessions
|
|
|
|
starting permutation: s2b s2txid s1init s3b s3txid s2alter s2c s2b s2txid s3c s2c s1insert s1checkpoint s1start s1insert s1alter s1insert s1start
|
|
step s2b: BEGIN;
|
|
step s2txid: SELECT txid_current() IS NULL;
|
|
?column?
|
|
|
|
f
|
|
step s1init: SELECT 'init' FROM pg_create_logical_replication_slot('isolation_slot', 'test_decoding'); <waiting ...>
|
|
step s3b: BEGIN;
|
|
step s3txid: SELECT txid_current() IS NULL;
|
|
?column?
|
|
|
|
f
|
|
step s2alter: ALTER TABLE do_write ADD COLUMN addedbys2 int;
|
|
step s2c: COMMIT;
|
|
step s2b: BEGIN;
|
|
step s2txid: SELECT txid_current() IS NULL;
|
|
?column?
|
|
|
|
f
|
|
step s3c: COMMIT;
|
|
step s1init: <... completed>
|
|
?column?
|
|
|
|
init
|
|
step s2c: COMMIT;
|
|
step s1insert: INSERT INTO do_write DEFAULT VALUES;
|
|
step s1checkpoint: CHECKPOINT;
|
|
step s1start: SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', 'false');
|
|
data
|
|
|
|
BEGIN
|
|
table public.do_write: INSERT: id[integer]:1 addedbys2[integer]:null
|
|
COMMIT
|
|
step s1insert: INSERT INTO do_write DEFAULT VALUES;
|
|
step s1alter: ALTER TABLE do_write ADD COLUMN addedbys1 int;
|
|
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');
|
|
data
|
|
|
|
BEGIN
|
|
table public.do_write: INSERT: id[integer]:2 addedbys2[integer]:null
|
|
COMMIT
|
|
BEGIN
|
|
COMMIT
|
|
BEGIN
|
|
table public.do_write: INSERT: id[integer]:3 addedbys2[integer]:null addedbys1[integer]:null
|
|
COMMIT
|
|
?column?
|
|
|
|
stop
|