pt-deadlock-logger
记录 MySQL 死锁(deadlock)信息——打印到 STDOUT 或保存到表中。
语法
pt-deadlock-logger [OPTIONS] DSN# 打印 host1 上的死锁
pt-deadlock-logger h=host1
# 打印一次后退出
pt-deadlock-logger h=host1 --iterations 1
# 把 host1 的死锁保存到 host2 的 percona_schema.deadlocks 表
pt-deadlock-logger h=host1 --dest h=host2,D=percona_schema,t=deadlocks用法示例
以下命令假定已通过 /etc/my.cnf、~/.my.cnf 或本机 socket 配置好 MySQL 连接;需用 DSN 显式指定连接时加 h=主机,P=端口,u=用户 或 F=/path/my.cnf(DSN 中不写明文密码)。命令可直接复制,替换其中的主机与库表名即可。
场景:实时查看死锁
现场排查死锁、想立刻在终端看到 SHOW ENGINE INNODB STATUS 中的死锁明细时,直接前台运行(默认每 30 秒轮询一次,永不退出,Ctrl-C 终止):
pt-deadlock-logger h=localhost场景:只抓一次就退出
做一次快照式检查(例如重启后想确认是否还有残留死锁),抓一轮后立即退出:
pt-deadlock-logger h=localhost --iterations 1场景:落库长期留存分析
把死锁存进数据库表,方便事后按 server/ts/thread 检索成因;表不存在时让工具自动建表:
pt-deadlock-logger h=localhost \
--dest D=percona_schema,t=deadlocks \
--create-dest-table场景:后台守护持续监控
生产环境需要 7×24 盯死锁,丢到后台并缩小轮询间隔、日志落盘:
pt-deadlock-logger h=localhost \
--daemonize --log /tmp/deadlock.log --interval 60s场景:精简列、制表符分隔
只关心发生时间、用户、库表与 SQL,且要便于导入表格/脚本分析,限定列并用制表符分隔:
pt-deadlock-logger h=localhost \
--columns ts,user,hostname,db,tbl,query --tab场景:清掉卡住的大死锁输出
当 SHOW ENGINE INNODB STATUS 被一个巨型死锁占满、导致正常死锁信息读不全时,让工具故意制造一个小死锁冲刷掉它(会自动建表再删表,仅用于诊断,勿在生产高峰期随意执行):
pt-deadlock-logger h=localhost \
--clear-deadlocks D=percona_schema,t=clear_deadlocks功能说明
通过轮询并解析 SHOW ENGINE INNODB STATUS 打印 MySQL 死锁信息。 出现新死锁时打印到 STDOUT,指定 --dest 时同时保存到表中。
只打印新的死锁:为每个死锁创建指纹(基于 server、ts、thread 值,即使这些列未包含在 --columns 中),指纹与上一个不同才打印。
--dest 写入使用 INSERT IGNORE 消除重复,因此每次 --iterations 都会保存每个死锁。
输出
新死锁打印到 STDOUT(--quiet 时不打印);错误与警告打印到 STDERR。 参见 --columns 与 --tab。
InnoDB 的注意事项
- InnoDB 输出难以解析,有时无法解析正确;并非所有信息(如用户名或 IP)都会包含在 死锁信息中,此时对应列无值可填;死锁输出过长(锁很多)时整体可能被截断。
- 死锁通常涉及两个事务,但锁的数量更多(至少比事务多一把锁才能在等待图中构成环)。 工具打印事务(InnoDB 输出中总是两个)并填充锁信息;选择锁信息时优先"等待中"的锁而非"持有中"的锁。 如果看到一把 wait-for 和一把 held 锁,那是同一把锁;如果两把 wait-for 锁不在同一张表上, 说明死锁涉及的事务超过两个。
- 由于 InnoDB 不给带空格的用户名加引号,这类用户名的第二个单词通常会被误报为主机名。
选项
| 选项 | 说明 |
|---|---|
--ask-pass | 连接 MySQL 时交互式询问密码 |
--[no]buffer-stdout | 默认开启 STDOUT 缓冲;使用 tee、kubectl logs 等后处理工具想看到实时进度时可关闭 |
-A, --charset | 类型:string。默认字符集(utf8 时设置 binmode/mysql_enable_utf8 并执行 SET NAMES UTF8) |
--clear-deadlocks | 类型:string。用该表制造一个小死锁,以清掉占据 SHOW INNODB STATUS 全部输出的大死锁。表必须不存在,工具会按 CREATE TABLE percona_schema.clear_deadlocks (a INT PRIMARY KEY) ENGINE=InnoDB 创建,事后删除 |
--columns | 类型:Array;默认:server, ts, thread, txn_id, txn_time, user, hostname, ip, db, tbl, idx, lock_type, lock_mode, wait_hold, victim, query。列含义:server=发生死锁的源服务器;ts=检测到最后一次死锁的时间;thread=MySQL 线程号(同 SHOW FULL PROCESSLIST 的连接 ID);txn_id=InnoDB 事务 ID(两个无符号整数相乘合成);txn_time=事务在死锁发生时已活跃的时长;user=连接的数据库用户;hostname=连接主机;ip=连接 IP(--numeric-ip 时转为无符号整数);db/tbl/idx=发生死锁的库/表/索引;lock_type/lock_mode=引发死锁的锁的类型与模式;wait_hold=事务在等待还是持有锁;victim=是否被选为死锁牺牲者回滚;query=引发死锁的查询 |
--config | 类型:Array。读取逗号分隔的配置文件列表;如指定必须放在命令行第一个选项的位置 |
--create-dest-table | 创建 --dest 指定的表(使用官方推荐表结构);默认要求 dest 表已存在 |
--daemonize | fork 到后台并与 shell 脱离,仅限 POSIX 系统 |
-D, --database | 类型:string。连接的数据库 |
-F, --defaults-file | 类型:string。只从给定文件读取 mysql 选项,必须给绝对路径 |
--dest | 类型:DSN。存储死锁的 DSN;至少指定数据库(D)和表(t)。缺失值从源主机 DSN 补齐。推荐表结构见官方文档(含 PRIMARY KEY (server,ts,thread));用 --columns 可省略不想存的列 |
--help | 显示帮助并退出 |
-h, --host | 类型:string。要连接的主机 |
--interval | 类型:time;默认:30。检查死锁的间隔 |
--iterations | 类型:int。检查次数;默认无限。--run-time 到期总是退出 |
--log | 类型:string。daemonize 时把全部输出打印到该文件 |
-s, --mysql_ssl | 类型:int。创建 SSL MySQL 连接 |
--numeric-ip | 把 IP 地址表示为整数 |
-p, --password | 类型:string。连接密码(含逗号需转义) |
--pid | 类型:string。创建指定的 PID 文件;冲突规则与自动清理见官方文档 |
-P, --port | 类型:int。连接端口 |
--quiet | 不打印死锁,只向 STDERR 打印错误与警告 |
--run-time | 类型:time。运行多久后退出;默认永远运行 |
--set-vars | 类型:Array。以逗号分隔的 变量=值 列表设置 MySQL 变量;默认 wait_timeout=10000;无法设置时打印警告并继续 |
-S, --socket | 类型:string。连接使用的 socket 文件 |
--tab | 用制表符而非空格分隔列 |
-u, --user | 类型:string。登录用户(若非当前用户) |
--version | 显示版本并退出 |
--[no]version-check | 默认:yes。检查 Percona Toolkit、MySQL 等软件的最新版本与已知问题版本(详见版本检查) |
DSN 选项
| 键 | DSN 部分 | 说明 |
|---|---|---|
A | charset | 默认字符集 |
D | database | 默认数据库 |
F | mysql_read_default_file | 只从给定文件读取默认选项 |
h | host | 要连接的主机 |
p | password | 连接密码(含逗号需转义) |
P | port | 连接端口 |
S | mysql_socket | 连接使用的 socket 文件 |
t | — | 存储死锁信息的表 |
u | user | 登录用户(若非当前用户) |
s | mysql_ssl | 创建 SSL 连接 |
其他信息
作者:Baron Schwartz 和 Daniel Nichter
通用说明:已知问题的反馈方式、PTDEBUG 调试安全提示、系统要求基线,见 通用说明。
更多细节请阅读 官方文档。