这是《MySQL 8.0 源码与内核实战》的独立章节版。本章从概念、实操和生产排查三个视角展开,代码块保留了原书可直接运行的版本。 性能诊断要先把问题定位到网络、锁、CPU、IO、优化器、执行器或 InnoDB,再用源码解释观测指标。
29.1 诊断路径
slow log
-> statement digest
-> EXPLAIN ANALYZE
-> performance_schema
-> OS metrics
-> source hypothesis
-> breakpoint / MTR
29.2 工具分层
| 层 | 工具 |
|---|---|
| SQL | slow log、EXPLAIN、ANALYZE |
| 语句等待 | performance_schema |
| 事务 | innodb_trx、data_locks |
| Buffer | Innodb_buffer_pool_* |
| IO | Innodb_data_*、iostat |
| OS | pidstat、perf、vmstat |
| 源码 | gdb、MTR |
29.3 慢 SQL
SELECT schema_name, digest_text, count_star,
sum_timer_wait/1e12 AS total_s
FROM performance_schema.events_statements_summary_by_digest
ORDER BY sum_timer_wait DESC
LIMIT 10;
判断:
| 特征 | 方向 |
|---|---|
| rows examined 高 | 索引、计划 |
| no index used | 访问路径 |
| Created_tmp_disk_tables | 排序聚合 |
| lock time 高 | MDL/行锁 |
| CPU 高 | 表达式、扫描 |
| IO wait 高 | Buffer、磁盘 |
29.4 等待事件
SELECT event_name, count_star, sum_timer_wait/1e12 AS total_s
FROM performance_schema.events_waits_summary_global_by_event_name
ORDER BY sum_timer_wait DESC
LIMIT 20;
常见映射:
| 等待 | 源码方向 |
|---|---|
| buffer pool mutex | buf 模块 |
| log sync | log 模块 |
| row lock | lock 模块 |
| undo purge | purge |
| file io | fil / buf |
| table lock | MDL |
29.5 常见问题定位
| 问题 | 排查 |
|---|---|
| commit 慢 | redo、binlog、磁盘 |
| DDL 等待 | MDL、长事务 |
| 大扫描 | 执行计划、索引 |
| 延迟尖刺 | checkpoint、purge、merge |
| CPU 单核高 | 单会话、锁模块 |
| IO 利用率高 | 冷数据、随机读 |
| history list 高 | 长事务 |
29.6 源码验证
# SQL path
b dispatch_command
b mysql_parse
b JOIN::optimize
# InnoDB read path
b row_search_mvcc
# write path
b row_insert_for_mysql
b row_update_for_mysql
# lock path
b lock_rec_lock
记录调用栈、参数、当前 THD 和事务状态,再对照源码结论。
本章小结
源码视角的性能诊断不是替代监控,而是解释监控指标。先用 slow log、EXPLAIN、等待事件和 OS 指标定位层,再用断点验证调用路径。
思考题
- rows examined 高说明什么?
- commit 延迟应从哪些模块排查?
- MDL 等待如何定位 blocking session?
- history list 高和哪个源码模块相关?
- 如何用 gdb 验证执行路径?