What kind of deadlock the deadlock_timeout config parameter detects in Postgresql?
3
votes
1
answer
7160
views
My overall goal is to get a
40P01/ERRCODE_T_R_DEADLOCK_DETECTED
from postgres when an deadlock is detected. (To be more precise, I would like to get a LockAcquisitionException in Hibernate, which is the exception the 40P01/ERRCODE_T_R_DEADLOCK_DETECTED
error code is translated in PostgreSQL81Dialect.java ) I use Postgresql 9.6.
For this I thought I should set the deadlock_timeout
and log_lock_waits
config variables
as suggested by 19.12. Lock Management
> deadlock_timeout
(integer) This is the amount of time, in
> milliseconds, to wait on a lock before checking to see if there is a
> deadlock condition.
> [...]
> When log_lock_waits
is set, this parameter also determines the length
> of time to wait before a log message is issued about the lock wait. If
> you are trying to investigate locking delays you might want to set a
> shorter than normal deadlock_timeout
.
I've set the following values in postgresql.conf
log_lock_waits = on # log lock waits >= deadlock_timeout
deadlock_timeout = 5s
Now, when I create a deadlock situtation (from Java using Hibernate) I find the following in the postgresql.log
LOG: process 17493 still waiting for ShareLock on transaction 322815 after 5000.464 ms
DETAIL: Process holding the lock: 17495. Wait queue: 17493.
CONTEXT: while updating tuple (132,35) in relation "publication"
However no 40P01/ERRCODE_T_R_DEADLOCK_DETECTED
error is generated (and sent to the JDBC driver).
I digged a little but into the postgres source code and found that the dead lock detection done by setting deadlock_timeout/log_lock_waits
is a different mechanism than the one generating 40P01/ERRCODE_T_R_DEADLOCK_DETECTED
. The deadlock_timeout
case is handled in backend/storage/lmgr/proc.c
, while the 40P01/ERRCODE_T_R_DEADLOCK_DETECTED
case in backend/storage/lmgr/deadlock.c
So, my questions are:
- Are these actually two different types of deadlocks that are detected?
- Is there a way to get an error when deadlock_timeout
based deadlock detection happens?
- How can actually a ERRCODE_T_R_DEADLOCK_DETECTED
error be forced to happen?
**UPDATE**: the code I use to get into the deadlock situation goes like this (Spring/Java):
// This is in a Transaction managed by spring
Publication p = em.find(Publication.class, id);
p.setComment("Outer "+new Date());
em.flush();
// This utility method runs the lambda expression in a new Transaction
// using Spring's TransactionTemplate and tries to update
// the same Publication that is about to be updated by the
// "outer" transaction
Utils.runInSeparateTransaction(status -> {
Publication p2 = em.find(p.getClass(), p.getMtid());
p2.setComment("Inner "+new Date());
return p2;
// Would flush/commit after the return, but will "hang" instead.
// Here I would expect the deadlock error but only get the
// deadlock log.
};
// Outer transaction would commit at this point but will
Asked by Balázs E. Pataki
(95 rep)
Jan 16, 2018, 10:13 AM
Last activity: Jun 29, 2018, 02:03 PM
Last activity: Jun 29, 2018, 02:03 PM