3. 慢查询日志分析工具:mysqldumpslow 与 pt-query-digest

MySQL 慢查询日志记录了执行时间超过 long_query_time 阈值的 SQL 语句。面对动辄数百 MB 甚至 GB 级别的原始日志,人工逐条分析几乎不可能。本章介绍两款最常用的慢查询日志分析工具:MySQL 官方自带的 mysqldumpslow 和 Percona 工具包中的 pt-query-digest,涵盖安装、基本用法和输出解读。

3.1 工具对比与选型

特性 mysqldumpslow pt-query-digest
来源 MySQL 官方自带(Perl 脚本) Percona Toolkit(需单独安装)
安装复杂度 零安装,随 MySQL 发布 需安装 perl 依赖及工具包
分析粒度 按 SQL 指纹聚合,输出摘要 按查询指纹聚合,支持多种输出格式
排序方式 支持按平均/总查询时间、锁时间、返回行数排序 支持按总耗时、平均耗时、响应时间占比、执行次数排序
输出格式 纯文本 文本、JSON、YAML、HTML 等
过滤能力 有限(按时间范围、正则) 强大(按数据库、用户、查询模式、时间范围等)
适用场景 快速查看、日常巡检、MySQL 原生环境 深度分析、报告生成、自动化监控集成
选型建议:日常快速排查使用 mysqldumpslow;需要生成详细报告、对接监控系统或进行复杂过滤时,优先使用 pt-query-digest。

3.2 mysqldumpslow 安装与使用

3.2.1 安装确认

mysqldumpslow 是 Perl 脚本,通常位于 MySQL 安装目录的 bin/ 子目录下。确认方式:

# 查找 mysqldumpslow 路径
which mysqldumpslow
# 或
find /usr -name "mysqldumpslow" 2>/dev/null

# 查看帮助
mysqldumpslow --help

如果系统提示找不到命令,可尝试从 MySQL 安装目录的 support-files/ 或 scripts/ 目录下查找并复制到 PATH 中。

3.2.2 常用参数

参数 说明 示例
-s 排序方式:t(查询时间)、l(锁时间)、r(返回行数)、c(执行次数) -s t
-t 只显示前 N 条 -t 10
-g 按正则过滤 SQL 内容 -g "SELECT.*user"
-a 不将数字抽象为 N,字符串抽象为 S -a
--verbose 显示更详细的信息 --verbose

3.2.3 典型用法

# 按平均查询时间降序,显示前 5 条
mysqldumpslow -s t -t 5 /var/log/mysql/slow-query.log

# 按执行次数降序,显示前 10 条
mysqldumpslow -s c -t 10 /var/log/mysql/slow-query.log

# 过滤包含特定表的慢查询
mysqldumpslow -g "orders" /var/log/mysql/slow-query.log

# 保留原始数字和字符串(不抽象)
mysqldumpslow -a -s t -t 20 /var/log/mysql/slow-query.log

3.2.4 输出解读

mysqldumpslow 的输出格式如下:

Count: 123  Time=2.34s (288s)  Lock=0.01s (1.23s)  Rows=100.0 (12300), root[root]@localhost
  SELECT * FROM orders WHERE status = 'S' AND create_time BETWEEN N AND N ORDER BY id DESC LIMIT N
  • Count:该 SQL 指纹的执行次数。
  • Time:平均执行时间(秒),括号内为总耗时。
  • Lock:平均锁等待时间,括号内为总锁时间。
  • Rows:平均返回行数,括号内为总返回行数。
  • 用户@主机:执行该查询的用户和客户端主机。
  • SQL 语句:经过抽象后的 SQL 模板(数字被替换为 N,字符串被替换为 S)。

3.3 pt-query-digest 安装与使用

3.3.1 安装 Percona Toolkit

pt-query-digest 是 Percona Toolkit 的核心工具之一。安装方式:

# CentOS / RHEL
yum install percona-toolkit

# Ubuntu / Debian
apt-get install percona-toolkit

# 或从官网下载 RPM/DEB 包手动安装
wget https://downloads.percona.com/downloads/percona-toolkit/3.5.5/binary/redhat/7/x86_64/percona-toolkit-3.5.5-1.el7.x86_64.rpm
rpm -ivh percona-toolkit-3.5.5-1.el7.x86_64.rpm

# 验证安装
pt-query-digest --version
依赖注意:Percona Toolkit 依赖 Perl 及若干 CPAN 模块(如 DBD::mysql、Time::HiRes 等)。如果安装过程中提示缺少模块,可使用 cpan 或系统包管理器安装对应 perl 模块。

3.3.2 常用参数

参数 说明 示例
--limit 限制输出前 N 条查询 --limit=20
--order-by 排序依据:Query_time:sum、Query_time:avg、Exec_count 等 --order-by=Query_time:sum
--filter 使用 Perl 表达式过滤查询 --filter '$event->{db} eq "mydb"'
--since / --until 按时间范围过滤 --since '2024-01-01 00:00:00' --until '2024-01-02 00:00:00'
--type 输入类型:slowlog、general-log、binlog、tcpdump 等 --type slowlog
--output 输出格式:report(默认)、json、yaml、html --output json
--review 将分析结果存入数据库表,便于历史对比 --review h=localhost,D=percona,t=query_review

3.3.3 典型用法

# 基本分析,按总耗时排序,显示前 10 条
pt-query-digest --limit=10 --order-by=Query_time:sum /var/log/mysql/slow-query.log

# 分析指定数据库的慢查询
pt-query-digest --filter '$event->{db} eq "ecommerce"' /var/log/mysql/slow-query.log

# 分析指定时间段的慢查询
pt-query-digest --since '2024-06-01 00:00:00' --until '2024-06-30 23:59:59' /var/log/mysql/slow-query.log

# 输出 JSON 格式,便于程序处理
pt-query-digest --output json /var/log/mysql/slow-query.log > slow_report.json

# 从 MySQL 进程列表直接分析(实时)
pt-query-digest --processlist h=localhost,u=root,p=password

3.3.4 输出解读

pt-query-digest 的输出分为三个主要部分:

  1. Overall:全局统计信息,包括总查询数、总耗时、唯一查询指纹数、时间范围等。
  2. Profile:按响应时间占比排序的查询指纹列表,每行显示占比、执行次数、平均耗时、标准差等。
  3. Query details:每个查询指纹的详细分析,包括样本 SQL、执行计划建议、响应时间分布直方图等。
关键指标:关注 Profile 中 Response time ratio(响应时间占比)最高的查询,它们通常是系统瓶颈。结合 Rows examine(扫描行数)和 Rows sent(返回行数)的比值,可判断是否存在全表扫描或索引缺失。

3.4 分析流程与最佳实践

下图展示了从慢查询日志采集到问题定位的完整分析流程:

慢查询日志分析流程 慢查询日志文件 选择分析工具 mysqldumpslow pt-query-digest 聚合摘要报告 详细分析报告 定位慢查询根因

3.5 实战案例:快速定位 TOP 慢查询

假设某电商平台数据库出现响应延迟,DBA 执行以下步骤快速定位问题:

# 步骤1:使用 mysqldumpslow 快速查看 TOP 10 慢查询
mysqldumpslow -s t -t 10 /var/log/mysql/slow-query.log

# 输出显示:
# Count: 456  Time=3.21s (1464s)  Lock=0.02s (9.12s)  Rows=500.0 (228000), root[root]@localhost
#   SELECT o.id, o.total_amount, u.name FROM orders o
#   JOIN users u ON o.user_id = u.id
#   WHERE o.status = 'S' AND o.create_time BETWEEN N AND N
#   ORDER BY o.create_time DESC LIMIT N

# 步骤2:使用 pt-query-digest 获取该查询的详细分析
pt-query-digest --filter '$event->{fingerprint} =~ m/SELECT.*orders.*users/' \
  /var/log/mysql/slow-query.log > order_slow_detail.txt

# 步骤3:查看分析报告中的 Query details 部分,关注:
# - 扫描行数 (Rows examine) 是否远大于返回行数 (Rows sent)
# - 响应时间分布直方图
# - EXPLAIN 建议
实战要点:
  • 先用 mysqldumpslow -s t -t 5 快速定位最耗时的查询指纹。
  • 再用 pt-query-digest --filter 对特定查询进行深度分析。
  • 结合 EXPLAIN 和 SHOW PROFILE 进一步确认索引使用情况和执行计划。
  • 定期(如每天)运行 pt-query-digest 并将结果存入 --review 表,便于趋势分析。

3.6 常见问题与避坑

问题 原因 解决方案
mysqldumpslow 输出为空 慢查询日志路径错误或日志为空 检查 slow_query_log_file 变量,确认日志文件存在且非空
pt-query-digest 报 DBD::mysql 错误 缺少 Perl MySQL 驱动 yum install perl-DBD-MySQL 或 apt-get install libdbd-mysql-perl
分析结果中 SQL 被抽象过度 mysqldumpslow 默认将数字替换为 N,字符串替换为 S 使用 -a 参数保留原始值
pt-query-digest 分析大文件耗时过长 日志文件过大(数 GB) 使用 --since 和 --until 缩小时间范围,或先按天分割日志
慢查询日志轮转后分析中断 日志文件被重命名或删除 配置 MySQL 的 log_slow_rotate 或使用 pt-query-digest --review 增量分析
重要提醒:在生产环境开启慢查询日志时,务必设置合理的 long_query_time(建议 1~2 秒)和 log_queries_not_using_indexes,避免日志量过大影响磁盘 I/O。同时配置日志轮转策略,防止磁盘空间被写满。