PostgreSQL 中的事后死锁调试
postmortem deadlock debugging in PostgreSQL
我想收集有关 PostgreSQL 死锁中 "winner" 事务和 "loser" 事务的 post-mortem 调试信息。
- 我发现 this 维基页面,其中包含一些很好的实时视图,可以提示 当前 出了什么问题,但如果我理解正确,到时候失败的交易已经被回滚大部分最有用的信息已经从这些实时视图中删除。
- 我看到了诸如 deadlock_timeout and log_lock_waits 之类的选项,它记录了有关失败交易的信息,但显然没有记录获胜交易的信息。似乎没有任何方法可以自定义生成的日志输出以包含比这更详细的信息(值得注意的是,当我事后基于日志进行调试时,这些整数的 none 意味着任何事情):
LOG: process 11367 still waiting for ShareLock on transaction 717 after 1000.108 ms
DETAIL: Process holding the lock: 11366. Wait queue: 11367.
CONTEXT: while updating tuple (0,2) in relation "foo"
STATEMENT: UPDATE foo SET value = 3;
我可以使用更好的数据源来收集这些信息吗?
首先,粘贴到问题中的跟踪不是死锁跟踪,而是关于资源锁定的警告,这些资源在足够长的时间内(超过 deadlock_timeout
)不可用。这不是错误,也不会中止事务,而死锁对事务来说是致命的。
I want to collect post-mortem debugging information about both the
"winner" transaction and the "loser" transaction(s) in a PostgreSQL
deadlock.
它们在服务器日志中,连同被终止的查询。
举个例子,这里有一个 log_line_prefix = '%t [%p] '
的死锁跟踪,用于这个问题中提到的案例:postgres deadlock without explicit locking
2015-04-09 15:16:42 CEST [21689] ERROR: deadlock detected
2015-04-09 15:16:42 CEST [21689] DETAIL: Process 21689 waits for ShareLock on transaction 1866436; blocked by process 21028.
Process 21028 waits for ShareLock on transaction 1866435; blocked by process 21689.
Process 21689: insert into b values(1);
Process 21028: insert into a values(1);
2015-04-09 15:16:42 CEST [21689] HINT: See server log for query details.
2015-04-09 15:16:42 CEST [21689] STATEMENT: insert into b values(1);
"looser" 是 PID 21689
作为错误的产生者。 "winner" 是 PID 21028
因为只是另一个。
如果从客户端的角度来看,它会得到这样的消息:
ERROR: deadlock detected
DETAIL: Process 21689 waits for ShareLock on transaction 1866436; blocked by process 21028.
Process 21028 waits for ShareLock on transaction 1866435; blocked by process 21689.
HINT: See server log for query details.
没有提及查询,但那是客户刚刚发送的查询。没有提到松散的,但它是得到这个错误的,另一个不需要注意任何东西。
我想收集有关 PostgreSQL 死锁中 "winner" 事务和 "loser" 事务的 post-mortem 调试信息。
- 我发现 this 维基页面,其中包含一些很好的实时视图,可以提示 当前 出了什么问题,但如果我理解正确,到时候失败的交易已经被回滚大部分最有用的信息已经从这些实时视图中删除。
- 我看到了诸如 deadlock_timeout and log_lock_waits 之类的选项,它记录了有关失败交易的信息,但显然没有记录获胜交易的信息。似乎没有任何方法可以自定义生成的日志输出以包含比这更详细的信息(值得注意的是,当我事后基于日志进行调试时,这些整数的 none 意味着任何事情):
LOG: process 11367 still waiting for ShareLock on transaction 717 after 1000.108 ms DETAIL: Process holding the lock: 11366. Wait queue: 11367. CONTEXT: while updating tuple (0,2) in relation "foo" STATEMENT: UPDATE foo SET value = 3;
我可以使用更好的数据源来收集这些信息吗?
首先,粘贴到问题中的跟踪不是死锁跟踪,而是关于资源锁定的警告,这些资源在足够长的时间内(超过 deadlock_timeout
)不可用。这不是错误,也不会中止事务,而死锁对事务来说是致命的。
I want to collect post-mortem debugging information about both the "winner" transaction and the "loser" transaction(s) in a PostgreSQL deadlock.
它们在服务器日志中,连同被终止的查询。
举个例子,这里有一个 log_line_prefix = '%t [%p] '
的死锁跟踪,用于这个问题中提到的案例:postgres deadlock without explicit locking
2015-04-09 15:16:42 CEST [21689] ERROR: deadlock detected 2015-04-09 15:16:42 CEST [21689] DETAIL: Process 21689 waits for ShareLock on transaction 1866436; blocked by process 21028. Process 21028 waits for ShareLock on transaction 1866435; blocked by process 21689. Process 21689: insert into b values(1); Process 21028: insert into a values(1); 2015-04-09 15:16:42 CEST [21689] HINT: See server log for query details. 2015-04-09 15:16:42 CEST [21689] STATEMENT: insert into b values(1);
"looser" 是 PID 21689
作为错误的产生者。 "winner" 是 PID 21028
因为只是另一个。
如果从客户端的角度来看,它会得到这样的消息:
ERROR: deadlock detected DETAIL: Process 21689 waits for ShareLock on transaction 1866436; blocked by process 21028. Process 21028 waits for ShareLock on transaction 1866435; blocked by process 21689. HINT: See server log for query details.
没有提及查询,但那是客户刚刚发送的查询。没有提到松散的,但它是得到这个错误的,另一个不需要注意任何东西。