MySQLNotes

第 30 章:监控告警

zjc 于 2026-01-30 发布

这是《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']

生产建议:

  1. exporter 独立账号;
  2. 只授监控权限;
  3. 采集频率 15 到 30 秒;
  4. 多实例统一标签;
  5. 监控采集本身不能拖垮数据库。

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 连接失败

告警方向:

  1. 连接使用率超过 80%;
  2. Threads_running 持续异常;
  3. Aborted_connects 快速增长;
  4. 大量长时间 Sleep;
  5. 连接池等待超时。

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])

解读:

  1. QPS 高不代表压力大;
  2. TPS 更能反映写事务压力;
  3. 必须与延迟、锁等待、IO 一起看;
  4. 突增要关联发布和活动;
  5. 基线按星期和小时建模。

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

指标:

  1. 每分钟慢查询数;
  2. 慢查询总耗时;
  3. 扫描行数;
  4. 返回行数;
  5. Top SQL 指纹;
  6. 新增慢 SQL;
  7. 锁等待时间;
  8. Rows examined / Rows sent。

推荐工具:

  1. pt-query-digest;
  2. 应用 APM;
  3. Elasticsearch / Loki 日志分析;
  4. 云厂商数据库洞察。

分析:

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

告警:

  1. 命中率持续下降;
  2. 行锁等待时间增长;
  3. Redo 等待非零增长;
  4. 脏页比例异常;
  5. 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;

建议监控:

  1. IO / SQL 线程状态;
  2. 位点差或 GTID 差;
  3. 心跳延迟;
  4. 复制错误码;
  5. Worker 队列;
  6. Relay Log 堆积;
  7. 主从切换事件。

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

告警:

  1. 事务年龄超过 60 秒;
  2. 单事务锁行数异常;
  3. 死锁速率增长;
  4. 锁等待队列增长;
  5. MDL 等待增长。

30.11 告警设计

告警分级:

级别 示例
P0 主库不可写、主从全断、磁盘满
P1 复制延迟超阈值、连接耗尽、死锁激增
P2 慢查询增长、Buffer Pool 命中率下降
P3 容量趋势异常、配置漂移

好告警特征:

  1. 有明确动作;
  2. 有阈值和持续时间;
  3. 关联业务影响;
  4. 不频繁误报;
  5. 包含实例、角色、机房标签;
  6. 指向 Runbook;
  7. 能区分主从角色。

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 容量趋势

每周评估:

  1. 数据增长率;
  2. Binlog 增长率;
  3. QPS / TPS 趋势;
  4. P99 延迟趋势;
  5. 连接峰值;
  6. Buffer Pool 命中率;
  7. 磁盘剩余天数;
  8. CPU 和 IO 水位;
  9. Top 表增长;
  10. 备份大小和恢复时间。

估算剩余天数:

剩余天数 = (总容量 - 当前使用量) / 日均增长

至少在磁盘、连接、CPU、IO、网络、备份窗口六项进入阈值前扩容。

本章小结

监控要覆盖业务、SQL、MySQL、InnoDB、复制、主机和存储,并把指标放在同一时间轴。告警应优先反映用户影响和饱和度,慢查询、锁等待、复制延迟、磁盘水位和长事务是数据库健康的核心信号。容量趋势要提前预测,而不是在磁盘满时救火。

思考题

  1. 数据库监控的黄金信号如何映射?
  2. 为什么 Seconds_Behind_Source 可能不可靠?
  3. 哪些指标适合 P0 / P1 告警?
  4. 如何监控长事务和 Undo 膨胀?
  5. 为你们 MySQL 集群设计一个核心仪表盘。