这是《MySQL 零基础实战指南》的独立章节版。本章从概念、实操和生产排查三个视角展开,代码块保留了原书可直接运行的版本。 没有监控的数据库等于黑盒。监控的目标不是收集所有指标,而是在问题影响用户前发现异常,并在事故中快速回答“哪里坏了、影响多大、该怎么处置”。
30.1 监控分层
| 层级 | 指标 |
|---|---|
| 业务 | 下单量、支付成功率、核心接口延迟 |
| 应用 | SQL 次数、错误、连接池等待、事务耗时 |
| MySQL | QPS、TPS、慢查询、连接、锁、临时表 |
| InnoDB | Buffer Pool、脏页、Redo、Undo、行锁 |
| 复制 | 线程状态、延迟、GTID、错误 |
| 主机 | CPU、内存、磁盘、网络、文件系统 |
| 存储 | IOPS、吞吐、延迟、云盘限流 |
业务指标要和数据库指标放在同一时间轴上,否则容易误判。
30.2 黄金信号
| 信号 | 数据库映射 |
|---|---|
| 延迟 | SQL P95 / P99、慢查询耗时 |
| 流量 | QPS、TPS、网络进出 |
| 错误 | SQL 错误、死锁、复制错误 |
| 饱和度 | CPU、IO、连接、锁等待、磁盘水位 |
告警应该优先围绕用户影响,而不是单个瞬时指标。
30.3 mysqld_exporter
Prometheus 常用 mysqld_exporter 采集 MySQL。
exporter 示例配置:
[client]
user=exporter
password=Exporter123456!
创建账号:
CREATE USER 'exporter'@'127.0.0.1' IDENTIFIED BY 'Exporter123456!';
GRANT PROCESS, REPLICATION CLIENT, SELECT ON *.*
TO 'exporter'@'127.0.0.1';
启动后 Prometheus 抓取:
scrape_configs:
- job_name: mysql
static_configs:
- targets: ['mysql-exporter:9104']
生产建议:
- exporter 独立账号;
- 只授监控权限;
- 采集频率 15 到 30 秒;
- 多实例统一标签;
- 监控采集本身不能拖垮数据库。
30.4 连接与线程
常用查询:
SHOW GLOBAL STATUS LIKE 'Threads%';
SHOW GLOBAL STATUS LIKE 'Connections';
SHOW GLOBAL STATUS LIKE 'Aborted%';
SHOW GLOBAL STATUS LIKE 'Max_used_connections';
重点指标:
| 指标 | 含义 |
|---|---|
Threads_connected |
当前连接 |
Threads_running |
当前活跃线程 |
Threads_created |
新建线程数 |
Max_used_connections |
历史最大连接 |
Aborted_clients |
客户端异常断开 |
Aborted_connects |
连接失败 |
告警方向:
- 连接使用率超过 80%;
Threads_running持续异常;Aborted_connects快速增长;- 大量长时间 Sleep;
- 连接池等待超时。
30.5 QPS / TPS
QPS 可用 Questions 估算,TPS 可用 Com_commit 与 Com_rollback 估算:
SHOW GLOBAL STATUS LIKE 'Questions';
SHOW GLOBAL STATUS LIKE 'Com_commit';
SHOW GLOBAL STATUS LIKE 'Com_rollback';
Prometheus 常用 rate 计算:
rate(mysql_global_status_questions[5m])
rate(mysql_global_status_commands_total{command="commit"}[5m])
解读:
- QPS 高不代表压力大;
- TPS 更能反映写事务压力;
- 必须与延迟、锁等待、IO 一起看;
- 突增要关联发布和活动;
- 基线按星期和小时建模。
30.6 慢查询
配置:
[mysqld]
slow_query_log = ON
long_query_time = 0.5
log_queries_not_using_indexes = ON
slow_query_log_file = /var/log/mysql/slow.log
指标:
- 每分钟慢查询数;
- 慢查询总耗时;
- 扫描行数;
- 返回行数;
- Top SQL 指纹;
- 新增慢 SQL;
- 锁等待时间;
- Rows examined / Rows sent。
推荐工具:
- pt-query-digest;
- 应用 APM;
- Elasticsearch / Loki 日志分析;
- 云厂商数据库洞察。
分析:
pt-query-digest /var/log/mysql/slow.log > slow_report.txt
30.7 InnoDB 指标
关键项:
| 指标 | 说明 |
|---|---|
| Buffer Pool hit rate | 缓存命中 |
| dirty pages | 脏页数量 |
Innodb_log_waits |
Redo 等待 |
Innodb_row_lock_waits |
行锁等待 |
Innodb_row_lock_time |
行锁等待时间 |
Innodb_buffer_pool_read_requests |
逻辑读 |
Innodb_buffer_pool_reads |
磁盘读 |
| History list length | Undo 积压 |
查看:
SHOW GLOBAL STATUS LIKE 'Innodb_row_lock%';
SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_read%';
SHOW ENGINE INNODB STATUS\G
告警:
- 命中率持续下降;
- 行锁等待时间增长;
- Redo 等待非零增长;
- 脏页比例异常;
- History list 持续增长。
30.8 复制监控
基础 SQL:
SHOW REPLICA STATUS\G
重点:
Replica_IO_Running
Replica_SQL_Running
Seconds_Behind_Source
Last_IO_Errno
Last_SQL_Errno
Retrieved_Gtid_Set
Executed_Gtid_Set
Performance Schema:
SELECT *
FROM performance_schema.replication_applier_status_by_worker;
建议监控:
- IO / SQL 线程状态;
- 位点差或 GTID 差;
- 心跳延迟;
- 复制错误码;
- Worker 队列;
- Relay Log 堆积;
- 主从切换事件。
Seconds_Behind_Source 不是唯一真相,推荐使用心跳表或 GTID 差值。
30.9 主机与存储
必须采集:
| 指标 | 说明 |
|---|---|
| CPU user / iowait | 计算和 IO 等待 |
| memory available | 可用内存 |
| disk usage | 数据、Binlog、临时目录 |
| disk IOPS / throughput | 磁盘负载 |
| IO latency | 读写延迟 |
| network in / out | 流量 |
| TCP retransmit | 网络质量 |
| fsync 延迟 | 提交延迟关键 |
MySQL 特殊目录:
datadir
log_bin
tmpdir
slow_log
relay_log
backup
磁盘使用率建议在 70% 到 80% 前告警,为 Binlog、备份、临时表和恢复预留空间。
30.10 事务与锁
当前事务:
SELECT
trx_id,
trx_started,
TIMESTAMPDIFF(SECOND, trx_started, NOW()) AS age_s,
trx_rows_locked,
trx_rows_modified
FROM information_schema.INNODB_TRX
ORDER BY trx_started;
锁等待:
SELECT *
FROM sys.innodb_lock_waits;
死锁:
SHOW GLOBAL STATUS LIKE 'Innodb_deadlocks';
SHOW ENGINE INNODB STATUS\G
告警:
- 事务年龄超过 60 秒;
- 单事务锁行数异常;
- 死锁速率增长;
- 锁等待队列增长;
- MDL 等待增长。
30.11 告警设计
告警分级:
| 级别 | 示例 |
|---|---|
| P0 | 主库不可写、主从全断、磁盘满 |
| P1 | 复制延迟超阈值、连接耗尽、死锁激增 |
| P2 | 慢查询增长、Buffer Pool 命中率下降 |
| P3 | 容量趋势异常、配置漂移 |
好告警特征:
- 有明确动作;
- 有阈值和持续时间;
- 关联业务影响;
- 不频繁误报;
- 包含实例、角色、机房标签;
- 指向 Runbook;
- 能区分主从角色。
Prometheus 示例:
mysql_global_status_threads_connected
/ on(instance) mysql_global_variables_max_connections > 0.85
rate(mysql_global_status_innodb_row_lock_waits[5m]) > 10
30.12 容量趋势
每周评估:
- 数据增长率;
- Binlog 增长率;
- QPS / TPS 趋势;
- P99 延迟趋势;
- 连接峰值;
- Buffer Pool 命中率;
- 磁盘剩余天数;
- CPU 和 IO 水位;
- Top 表增长;
- 备份大小和恢复时间。
估算剩余天数:
剩余天数 = (总容量 - 当前使用量) / 日均增长
至少在磁盘、连接、CPU、IO、网络、备份窗口六项进入阈值前扩容。
本章小结
监控要覆盖业务、SQL、MySQL、InnoDB、复制、主机和存储,并把指标放在同一时间轴。告警应优先反映用户影响和饱和度,慢查询、锁等待、复制延迟、磁盘水位和长事务是数据库健康的核心信号。容量趋势要提前预测,而不是在磁盘满时救火。
思考题
- 数据库监控的黄金信号如何映射?
- 为什么
Seconds_Behind_Source可能不可靠? - 哪些指标适合 P0 / P1 告警?
- 如何监控长事务和 Undo 膨胀?
- 为你们 MySQL 集群设计一个核心仪表盘。