Re: Prepared transaction releasing locks before deregistering its GID
Michael Paquier <michael@paquier.xyz>
From: Michael Paquier <michael@paquier.xyz>
To: Masahiko Sawada <sawada.mshk@gmail.com>
Cc: Oleksii Kliukin <alexk@hintbits.com>, PostgreSQL-development <pgsql-hackers@postgresql.org>
Date: 2019-02-20T08:22:01Z
Lists: pgsql-hackers
Attachments
- 2pc-commit-locks-v2.patch (text/x-diff) patch v2
On Wed, Feb 20, 2019 at 03:14:07PM +0900, Masahiko Sawada wrote: > @@ -811,6 +811,9 @@ TwoPhaseGetGXact(TransactionId xid) > static TransactionId cached_xid = InvalidTransactionId; > static GlobalTransaction cached_gxact = NULL; > > + Assert(!lock_held || > + LWLockHeldByMeInMode(TwoPhaseStateLock, LW_EXCLUSIVE)); > + > > It seems strange to me, why do we always require an exclusive lock > here in spite of acquiring a shared lock? Thanks for looking at the patch. LWLockHeldByMe() is fine here. It seems that I had a brain fade. > TwoPhaseGetDummyBackendId() is called by > multixact_twophase_postcommit() which is called while holding > TwoPhaseStateLock in exclusive mode in FinishPreparedTransaction(). > Since we cache the global transaction when we call > lock_twophase_commit() I couldn't produce issue but it seems to have a > potential of locking problem. You are right: this could cause a deadlock problem, but it actually cannot be triggered now because the repetitive calls of TwoPhaseGetGXact() make the resulting XID to be cached, so the lock finishes by never be taken, but that could become broken in the future. From a consistency point of view, adding the same option to TwoPhaseGetGXact() and TwoPhaseGetGXact() to control the lock acquisition is much better as well. Please note that the recovery tests stress multixact post-commit callbacks already, so you can see the caching behavior with that one: BEGIN; CREATE TABLE t_009_tbl2 (id int, msg text); SAVEPOINT s1; INSERT INTO t_009_tbl2 VALUES (27, 'issued to stuff'); PREPARE TRANSACTION 'xact_009_13'; CHECKPOINT; COMMIT PREPARED 'xact_009_13'; The assertion really needs to be before the cached XID is checked though. Attached is an updated patch. Thanks for the feedback. -- Michael
Commits
-
Make release of 2PC identifier and locks consistent in COMMIT PREPARED
- effe7d9552dd 12.0 landed
-
Fix incorrect function reference in comment of twophase.c
- 4c23216002ac 12.0 landed
-
Add TAP tests for 2PC post-commit callbacks of multixacts at recovery
- b1086767087e 12.0 landed