Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit955a684

Browse files
committed
Fix race condition leading to hanging logical slot creation.
The snapshot assembly during the creation of logical slots reliedwaiting for transactions in xl_running_xacts to end, by checking fortheir commit/abort records. Unfortunately, despite locking, it ispossible to see an xl_running_xact record listing transactions asready, that have already WAL-logged an commit/abort record, as thelocking just prevents the ProcArray to be adjusted, and the commitrecord has to be logged first.That lead to either delayed or hanging snapshot creation, becausesnapbuild.c would wait "forever" to see commit/abort records for sometransactions. That hang resolved only if a xl_running_xacts recordwithout any running transactions happened to be logged, far fromcertain on a busy server.It's impractical to prevent that via more heavyweight locking, thelikelihood of deadlocks and significantly increased contention wouldbe too big.Instead change the initial snapshot creation to be solely based ontracking the oldest running transaction viaxl_running_xacts->oldestRunningXid - that actually ends upsignificantly 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 fromwithin snapbuild.c exactly when necessary.Unfortunately snabuild.c's SnapBuild is stored on disk, one of thestupider ideas of a certain Mr Freund, so we can't change it in aminor release. As this is going to be backpatched, we have to hackaround a bit to keep on-disk compatibility. A later commit willrejigger that on master.Author: Andres Freund, based on a quite different patch from Petr JelinekAnalyzed-By: Petr JelinekReviewed-By: Petr JelinekDiscussion:https://postgr.es/m/f37e975c-908f-858e-707f-058d3b1eb214@2ndquadrant.comBackpatch: 9.4-, where logical decoding has been introduced
1 parent9aab83f commit955a684

File tree

6 files changed

+220
-249
lines changed

6 files changed

+220
-249
lines changed

‎contrib/test_decoding/expected/ondisk_startup.out

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,30 @@
11
Parsed test spec with 3 sessions
22

3-
starting permutation: s2txid s1init s3txid s2alter s2c s1insert s1checkpoint s1start s1insert s1alter s1insert s1start
4-
step s2txid: BEGIN ISOLATION LEVEL REPEATABLE READ; SELECT txid_current() IS NULL;
3+
starting permutation: s2b s2txid s1init s3b s3txid s2alter s2c s2b s2txid s3c s2c s1insert s1checkpoint s1start s1insert s1alter s1insert s1start
4+
step s2b: BEGIN;
5+
step s2txid: SELECT txid_current() IS NULL;
56
?column?
67

78
f
89
step s1init: SELECT 'init' FROM pg_create_logical_replication_slot('isolation_slot', 'test_decoding'); <waiting ...>
9-
step s3txid: BEGIN ISOLATION LEVEL REPEATABLE READ; SELECT txid_current() IS NULL;
10+
step s3b: BEGIN;
11+
step s3txid: SELECT txid_current() IS NULL;
1012
?column?
1113

1214
f
1315
step s2alter: ALTER TABLE do_write ADD COLUMN addedbys2 int;
1416
step s2c: COMMIT;
17+
step s2b: BEGIN;
18+
step s2txid: SELECT txid_current() IS NULL;
19+
?column?
20+
21+
f
22+
step s3c: COMMIT;
1523
step s1init: <... completed>
1624
?column?
1725

1826
init
27+
step s2c: COMMIT;
1928
step s1insert: INSERT INTO do_write DEFAULT VALUES;
2029
step s1checkpoint: CHECKPOINT;
2130
step s1start: SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', 'false');

‎contrib/test_decoding/specs/ondisk_startup.spec

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,20 +24,22 @@ step "s1alter" { ALTER TABLE do_write ADD COLUMN addedbys1 int; }
2424
session"s2"
2525
setup {SETsynchronous_commit=on; }
2626

27-
step"s2txid" {BEGINISOLATIONLEVELREPEATABLEREAD;SELECTtxid_current()ISNULL; }
27+
step"s2b" {BEGIN; }
28+
step"s2txid" {SELECTtxid_current()ISNULL; }
2829
step"s2alter" {ALTERTABLEdo_writeADDCOLUMNaddedbys2int; }
2930
step"s2c" {COMMIT; }
3031

3132

3233
session"s3"
3334
setup {SETsynchronous_commit=on; }
3435

35-
step"s3txid" {BEGINISOLATIONLEVELREPEATABLEREAD;SELECTtxid_current()ISNULL; }
36+
step"s3b" {BEGIN; }
37+
step"s3txid" {SELECTtxid_current()ISNULL; }
3638
step"s3c" {COMMIT; }
3739

3840
# Force usage of ondisk snapshot by starting and not finishing a
3941
# transaction with an assigned xid after consistency has been
4042
# reached. In combination with a checkpoint forcing a snapshot to be
4143
# written and a new restart point computed that'll lead to the usage
4244
# of the snapshot.
43-
permutation"s2txid""s1init""s3txid""s2alter""s2c""s1insert""s1checkpoint""s1start""s1insert""s1alter""s1insert""s1start"
45+
permutation"s2b""s2txid""s1init""s3b""s3txid""s2alter""s2c""s2b""s2txid""s3c""s2c""s1insert""s1checkpoint""s1start""s1insert""s1alter""s1insert""s1start"

‎src/backend/replication/logical/decode.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -622,9 +622,6 @@ DecodeAbort(LogicalDecodingContext *ctx, XLogRecordBuffer *buf,
622622
{
623623
inti;
624624

625-
SnapBuildAbortTxn(ctx->snapshot_builder,buf->record->EndRecPtr,xid,
626-
parsed->nsubxacts,parsed->subxacts);
627-
628625
for (i=0;i<parsed->nsubxacts;i++)
629626
{
630627
ReorderBufferAbort(ctx->reorder,parsed->subxacts[i],

‎src/backend/replication/logical/reorderbuffer.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1725,7 +1725,7 @@ ReorderBufferAbortOld(ReorderBuffer *rb, TransactionId oldestRunningXid)
17251725

17261726
if (TransactionIdPrecedes(txn->xid,oldestRunningXid))
17271727
{
1728-
elog(DEBUG1,"aborting old transaction %u",txn->xid);
1728+
elog(DEBUG2,"aborting old transaction %u",txn->xid);
17291729

17301730
/* remove potential on-disk data, and deallocate this tx */
17311731
ReorderBufferCleanupTXN(rb,txn);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp