SQL 如何排查“死锁” Deadlock detected 的详细日志分析-SQL

PostgreSQL死锁日志需同时满足log_min_messages≥ERROR且log_lock_waits=on,核心是连续三段式输出:ERROR行+两个DETAIL块,分别描述victim事务和阻塞事务的进程号、SQL、等待锁、持有锁及物理上下文。

怎么看 PostgreSQL 的 deadlock 日志条目

PostgreSQL 默认在 log_min_messages ≥ ERROR 且 log_lock_waits 开启时,才会记录死锁事件。真正关键的是日志里连续出现的三段式输出:一个 ERROR: deadlock detected 错误行,紧接着是两个(或多个)DETAIL: 块,分别描述被选为 victim 的事务和另一个/多个阻塞它的事务。

重点看每段 DETAIL: 里的这几项:

  • Process XXXX: UPDATE t1 SET x = 1 WHERE id = 100 —— 进程号 + 当前正在执行的 SQL
  • Waiting for ShareLock on transaction YYYYY —— 它卡在等哪个事务释放锁
  • Process ZZZZ: SELECT * FROM t2 WHERE id = 200 FOR UPDATE —— 另一个进程的 SQL,它持有了前者需要的锁
  • Context: while updating tuple (0,1) in relation "t1" —— 具体到页和行的物理位置(对排查热点行很有用)

如何定位死锁涉及的表、索引与事务顺序

从日志中提取出所有出现的 UPDATE/DELETE/SELECT ... FOR UPDATE 语句,逐条检查它们是否:

  • 操作了相同表但顺序相反:比如事务 A 先更新 t1 再更新 t2,事务 B 却先 t2 后 t1 —— 这是最常见根源
  • 用了不同索引路径:同一条 UPDATE 在不同事务中因 WHERE 条件走不同索引,导致加锁顺序不一致
  • 隐式锁升级:例如 UPDATE 本该只锁匹配行,但因缺失索引导致全表扫描,实际锁了整页甚至整个二级索引
  • 触发器或函数调用引入了额外 DML:日志里没显示,但实际执行流中悄悄改了另一张表

用 \d+ 表名 查索引定义,用 EXPLAIN (ANALYZE, BUFFERS) 对比各条 SQL 的执行计划,确认锁范围是否预期一致。

MySQL 的 InnoDB deadlock log 怎么读(show engine innodb status 输出)

MySQL 不写 error log,而是把最近一次死锁详情塞进 SHOW ENGINE INNODB STATUS 的 LATEST DETECTED DEADLOCK 区块。注意这个输出只保留最后一次,要抓实时日志得靠定期轮询或开启 innodb_print_all_deadlocks = ON(写入 error log)。

夏夕资源网专注于CMS网站模板,主流语言整站网站源码下载,网站建设相关教程分享,好用的软件素材整合下载,提供一站式便捷自助服务。
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需!
7. 如遇到加密压缩包,默认解压密码为"zy.lucklyus.top",如遇到无法解压的请联系管理员!
夏夕资源网-网站模板_免费源码_资源素材 » SQL 如何排查“死锁” Deadlock detected 的详细日志分析-SQL
在线时间:12:00 - 22:00
关注微信公众号:微信公众号
站长邮箱:[email protected]
  • 运营天数: 1391+
  • 资源总数: 47989+
  • 用户总数: 1+
  • 今日更新: 0+
  • 访问次数: 3995616+
  • 本周更新: 0+
  • 最后更新: 2026-03-16

本站指数

×
  • 运营天数: 1391+
  • 资源总数: 47989+
  • 用户总数: 1+
  • 今日更新: 0+
  • 访问次数: 3995616+
  • 本周更新: 0+
  • 最后更新: 2026-03-16