0

0

SQL 如何排查死锁(Deadlock detected)的日志解读模板

舞夢輝影

舞夢輝影

发布时间:2026-01-28 21:31:02

|

852人浏览过

|

来源于php中文网

原创

PostgreSQL死锁日志需重点定位互锁的进程PID、事务ID、锁对象及具体SQL;结合pg_stat_activity查活跃会话与query,确认未提交事务;索引不能避免所有死锁,锁范围受隔离级别、执行计划影响;修复关键在于统一所有业务路径的加锁顺序。

sql 如何排查死锁(deadlock detected)的日志解读模板

怎么看 PostgreSQL 的 deadlock detected 错误日志

PostgreSQL 在发生死锁时会主动中止其中一个事务,并在日志里输出带 deadlock detected 的错误行。关键不是“有没有报错”,而是要从日志里快速定位哪两个(或多个)事务、哪几条 SQL、锁在了哪些对象上。

典型日志片段长这样:

ERROR:  deadlock detected
DETAIL:  Process 12345 waits for ShareLock on transaction 67890; blocked by process 6789.
Process 6789 waits for ShareLock on transaction 12345; blocked by process 12345.
HINT:  See server log for query details.
CONTEXT:  while updating tuple (123,45) in relation "orders"
  • Process 12345Process 6789操作系统级的 backend PID,可结合 pg_stat_activity 查当前会话
  • transaction 67890transaction 12345 是内部事务 ID,不能直接查,但能说明循环等待发生在两个事务之间
  • ShareLock on transaction ... 表示是事务级锁冲突(常见于 SERIALIZABLE 隔离级别),不是行锁或表锁;若看到 RowExclusiveLock on relation "xxx",则是普通 DML 引发的行级死锁
  • while updating tuple (123,45) in relation "orders" 是最实用的线索:说明卡在更新 orders 表第 123 页第 45 行——结合表结构和索引,基本能反推出被锁的主键或唯一键值

如何关联到具体 SQL 和会话状态

单看错误日志不够,必须立刻查 pg_stat_activity 抓快照,尤其是死锁发生前后 10 秒内的活跃会话。重点过滤 state = 'active'state = 'idle in transaction' 的记录,并按 backend_pid 匹配日志里的进程号。

  • SELECT pid, usename, application_name, client_addr, backend_start, state_change, query FROM pg_stat_activity WHERE pid IN (12345, 6789); 查对应会话正在执行的 query
  • 注意 state_change 时间戳是否接近死锁日志时间——若差几秒内,大概率就是它
  • 如果 query 显示为 或截断严重,说明语句已执行完但事务未提交,此时要看 backend_startxact_start 判断事务挂了多久
  • 对长期 idle in transaction 的会话,要检查应用层是否漏了 COMMITROLLBACK,这是死锁高频诱因

为什么加了索引还是死锁?关键看锁范围

很多人以为“只要 WHERE 条件走索引,就只锁匹配行”,但 PostgreSQL 的锁行为受隔离级别、语句类型、执行计划共同影响。例如:

BibiGPT-哔哔终结者
BibiGPT-哔哔终结者

B站视频总结器-一键总结 音视频内容

下载
  • UPDATE orders SET status = 'shipped' WHERE user_id = 123; —— 若 user_id 没有索引,会全表扫描并锁住所有扫描过的行(甚至页),大幅增加死锁概率
  • 即使 user_id 有索引,若优化器选了 Bitmap Heap Scan + Recheck,也可能临时锁住非目标行
  • SELECT ... FOR UPDATE 在可重复读下会锁住所有扫描到的可见行(包括已删除但未清理的 dead tuple),而不仅限于最终返回结果
  • 批量操作如 UPDATE ... WHERE id IN (1,2,3,4,5),若这些 id 在物理存储上不连续,锁顺序可能和应用执行顺序不一致,形成环路

怎么复现和验证修复效果

死锁无法靠日志“修好”,必须在测试环境模拟相同访问模式。不要依赖随机压测,要精准控制事务顺序:

  • 用两个 psql 会话,手动执行两段 SQL,严格按生产中出现的交叉顺序:比如会话 A 先 UPDATE t1UPDATE t2,会话 B 反过来先 UPDATE t2UPDATE t1
  • 在每个 UPDATE 后加 SELECT pg_sleep(0.1); 延迟,放大竞争窗口
  • 修复后验证重点不是“还死不死”,而是看 pg_locks 中锁的持有顺序是否统一:所有事务都按 t1 → t2 → t3 的固定顺序加锁,就能彻底避免环路
  • 上线前务必检查 ORM 是否隐式启用了 FOR UPDATE 或自动拆分批量更新(如 Djangobulk_update 在某些版本会逐条执行)

真正难的不是识别死锁,而是确认所有业务路径下的锁顺序是否收敛——尤其当微服务间通过消息队列异步触发 DB 操作时,锁顺序很容易被拆散。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
数据分析工具有哪些
数据分析工具有哪些

数据分析工具有Excel、SQL、Python、R、Tableau、Power BI、SAS、SPSS和MATLAB等。详细介绍:1、Excel,具有强大的计算和数据处理功能;2、SQL,可以进行数据查询、过滤、排序、聚合等操作;3、Python,拥有丰富的数据分析库;4、R,拥有丰富的统计分析库和图形库;5、Tableau,提供了直观易用的用户界面等等。

727

2023.10.12

SQL中distinct的用法
SQL中distinct的用法

SQL中distinct的语法是“SELECT DISTINCT column1, column2,...,FROM table_name;”。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

327

2023.10.27

SQL中months_between使用方法
SQL中months_between使用方法

在SQL中,MONTHS_BETWEEN 是一个常见的函数,用于计算两个日期之间的月份差。想了解更多SQL的相关内容,可以阅读本专题下面的文章。

350

2024.02.23

SQL出现5120错误解决方法
SQL出现5120错误解决方法

SQL Server错误5120是由于没有足够的权限来访问或操作指定的数据库或文件引起的。想了解更多sql错误的相关内容,可以阅读本专题下面的文章。

1242

2024.03.06

sql procedure语法错误解决方法
sql procedure语法错误解决方法

sql procedure语法错误解决办法:1、仔细检查错误消息;2、检查语法规则;3、检查括号和引号;4、检查变量和参数;5、检查关键字和函数;6、逐步调试;7、参考文档和示例。想了解更多语法错误的相关内容,可以阅读本专题下面的文章。

360

2024.03.06

oracle数据库运行sql方法
oracle数据库运行sql方法

运行sql步骤包括:打开sql plus工具并连接到数据库。在提示符下输入sql语句。按enter键运行该语句。查看结果,错误消息或退出sql plus。想了解更多oracle数据库的相关内容,可以阅读本专题下面的文章。

820

2024.04.07

sql中where的含义
sql中where的含义

sql中where子句用于从表中过滤数据,它基于指定条件选择特定的行。想了解更多where的相关内容,可以阅读本专题下面的文章。

581

2024.04.29

sql中删除表的语句是什么
sql中删除表的语句是什么

sql中用于删除表的语句是drop table。语法为drop table table_name;该语句将永久删除指定表的表和数据。想了解更多sql的相关内容,可以阅读本专题下面的文章。

423

2024.04.29

俄罗斯Yandex引擎入口
俄罗斯Yandex引擎入口

2026年俄罗斯Yandex搜索引擎最新入口汇总,涵盖免登录、多语言支持、无广告视频播放及本地化服务等核心功能。阅读专题下面的文章了解更多详细内容。

158

2026.01.28

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Go 教程
Go 教程

共32课时 | 4.3万人学习

Go语言实战之 GraphQL
Go语言实战之 GraphQL

共10课时 | 0.8万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号