如何定位数据库死锁问题

50 天前
 superhot
看日志只知道在更新表数据时发生了 MySQL 40001 死锁错误 要想定位具体问题点 都有哪些角度可以考虑呢?
1396 次点击
所在节点    数据库
4 条回复
shyrock
50 天前
pg 可以查询 lock 表来找到锁定和被锁的 pid 以及各自执行的 sql 语句。如下
SELECT blocked_locks.pid AS blocked_pid,
blocked_activity.usename AS blocked_user,
blocked_activity.query AS blocked_statement,
blocking_locks.pid AS blocking_pid,
blocking_activity.usename AS blocking_user,
blocking_activity.query AS current_statement_in_blocking_process
FROM pg_catalog.pg_locks blocked_locks
JOIN pg_catalog.pg_stat_activity blocked_activity ON blocked_activity.pid = blocked_locks.pid
JOIN pg_catalog.pg_locks blocking_locks
ON blocking_locks.locktype = blocked_locks.locktype
AND blocking_locks.database is not distinct FROM blocked_locks.database AND blocking_locks.relation is not distinct FROM blocked_locks.relation
AND blocking_locks.page is not distinct FROM blocked_locks.page
AND blocking_locks.tuple is not distinct FROM blocked_locks.tuple
AND blocking_locks.virtualxid is not distinct FROM blocked_locks.virtualxid
AND blocking_locks.transactionid is not distinct FROM blocked_locks.transactionid
AND blocking_locks.classid is not distinct FROM blocked_locks.classid
AND blocking_locks.objid is not distinct FROM blocked_locks.objid
AND blocking_locks.objsubid is not distinct FROM blocked_locks.objsubid
AND blocking_locks.pid != blocked_locks.pid
JOIN pg_catalog.pg_stat_activity blocking_activity ON blocking_activity.pid = blocking_locks.pid
where NOT blocked_locks.granted;

MySQL 应该有类似的表可以查吧。
maierhuang
50 天前
死锁数据库检测到直接会回滚掉其中一个事务,所以一般是事后查。开启 innodb_print_all_deadlocks 死锁日志打印,或者 show engine innodb status,里面会打印最近一条检测到的死锁日志。不过死锁一般不是单条 sql 引擎,一般是两个事务之间,但日志里面不会打印整个事务的全貌。所以日志里面查到对应的信息后,要回过头去看对应程序里面的事务逻辑。
superhot
50 天前
@shyrock
@maierhuang
感谢二位 我再研究研究
a7851578
49 天前

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1061444

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX