17_MySQL 监控体系构建 ------ mysqld_exporter + Prometheus + Grafana 全栈实战
系列定位 :《MySQL 数据库全栈运维实战系列》第 17 篇,与《Oracle 数据库全栈运维实战系列(VMware 版)》同构对标(Oracle 17 监控体系:oracledb_exporter + Prometheus + Grafana)。适用版本 :MySQL 8.0(5.7 差异随文标注)。官方文档:mysqld_exporter(GitHub)、Prometheus / Grafana 官方文档、MySQL 8.0 System Status Variables。
一、监控体系架构(全景图)

图 1

图 2
| 层 | 组件 | 端口 | 说明 |
|---|---|---|---|
| 采集 | mysqld_exporter | 9104 | 每个 MySQL 实例一个 |
| 采集 | node_exporter | 9100 | 每台主机一个 |
| 存储 | Prometheus | 9090 | 时序库 + 告警规则 |
| 展示 | Grafana | 3000 | 看板 |
| 告警 | Alertmanager | 9093 | 收敛 + 分发 |
二、指标分层(mysqld_exporter 真实指标)
2.1 指标来源

图 3
2.2 MySQL 指标清单与 Oracle 对照(本篇核心:逐指标对标)
| 分类 | mysqld_exporter 指标 | 含义 | 类比 Oracle 指标 | 告警阈值 |
|---|---|---|---|---|
| 存活 | mysql_up |
采集/实例是否正常 | oracle_up |
=0 即 P0 |
| 运行时长 | mysql_global_status_uptime |
实例秒级运行时长 | oracle_instance_uptime_seconds |
突降=重启 |
| 连接数 | mysql_global_status_threads_connected |
当前连接数 | oracle_sessions_total |
超 80% max_connections |
| 活跃线程 | mysql_global_status_threads_running |
活跃线程 | oracle_sessions_active_total |
持续偏高 |
| 连接峰值 | mysql_global_status_connections(rate) |
新建连接速率 | --- | 突增=连接风暴 |
| 连接失败 | mysql_global_status_aborted_connects(rate) |
失败/断开连接 | --- | 突增 |
| 最大连接 | mysql_global_variables_max_connections |
连接上限 | oracle_sessions_limit |
--- |
| 命中率 | Buffer Pool 命中率* | 数据页缓存命中 | oracle_buffer_cache_hit_ratio |
低于 99% |
| 慢查询 | mysql_global_status_slow_queries(rate) |
慢查询数 | --- | 突增 |
| QPS/TPS | mysql_global_status_com_select 等 |
读写速率 | DB Time 速率 | 趋势 |
| 临时表 | mysql_global_status_created_tmp_disk_tables(rate) |
落盘临时表 | --- | 偏高=缺索引/排序大 |
| 表锁 | mysql_global_status_table_locks_waited(rate) |
等待表锁次数 | enq 等待 | 大于 0 关注 |
| InnoDB 行锁 | mysql_global_status_innodb_row_lock_waits(rate) |
行锁等待 | 行锁等待事件 | 偏高 |
| binlog 缓存 | mysql_global_status_binlog_cache_disk_use(rate) |
binlog 落盘 | --- | 偏高=调大 binlog_cache_size |
| 从库 IO | mysql_slave_status_slave_io_running |
从库 IO 线程 | DG transport | =0 P0 |
| 从库 SQL | mysql_slave_status_slave_sql_running |
从库 SQL 线程 | DG apply | =0 P0 |
| 复制延迟 | mysql_slave_status_seconds_behind_master |
主从延迟(秒) | oracle_dg_apply_lag_seconds |
超 60s P1 |
| 实例信息 | mysql_global_variables_version |
版本信息 | oracle_instance_info |
--- |
*Buffer Pool 命中率 =
1 - innodb_buffer_pool_reads / innodb_buffer_pool_read_requests,用 PromQL 计算(见 4.3)。
对照表小结 :Oracle 侧oracle_*指标在 MySQL 侧几乎都能找到对应------mysql_up↔oracle_up、threads_connected↔sessions_total、Buffer 命中率↔Buffer Cache 命中率、seconds_behind_master↔dg_apply_lag。看板与告警规则把oracle_前缀换成mysql_即可整体迁移(Oracle 17 篇的看板骨架可直接复用)。
三、部署 mysqld_exporter
3.1 流程

图 4
3.2 实施(命令 + 解释)
-- ① 建监控账号(解释:只读即可,mysql.sys 风格)
CREATE USER 'exporter'@'127.0.0.1' IDENTIFIED BY 'Exp@Pass2026' WITH MAX_USER_CONNECTIONS 3;
GRANT PROCESS, REPLICATION CLIENT, SELECT ON *.* TO 'exporter'@'127.0.0.1';
-- 解释:PROCESS 看线程、REPLICATION CLIENT 看复制状态、SELECT 读 info_schema
# ② 下载(解释:官方 GitHub 发行版)
wget https://github.com/prometheus/mysqld_exporter/releases/download/v0.15.1/mysqld_exporter-0.15.1.linux-amd64.tar.gz
tar xzf mysqld_exporter-0.15.1.linux-amd64.tar.gz
mv mysqld_exporter-0.15.1.linux-amd64 /usr/local/mysqld_exporter
# ③ 写认证文件(解释:~/.my.cnf 方式传 DSN,避免命令行明文密码)
cat > /usr/local/mysqld_exporter/.my.cnf <<'EOF'
[client]
user=exporter
password=Exp@Pass2026
host=127.0.0.1
port=3306
EOF
chmod 600 /usr/local/mysqld_exporter/.my.cnf
# ④ 启动(解释:默认端口 9104)
/usr/local/mysqld_exporter/mysqld_exporter \
--config.my-cnf=/usr/local/mysqld_exporter/.my.cnf \
--web.listen-address=:9104
# ⑤ 验证(解释:curl 能看到 mysql_up=1 即成功)
curl -s http://127.0.0.1:9104/metrics | grep -E '^mysql_up|^mysql_global_status_uptime'
3.3 systemd 托管
# /etc/systemd/system/mysqld_exporter.service
[Unit]
Description=MySQL Exporter
After=network.target mysqld.service
[Service]
User=mysql
ExecStart=/usr/local/mysqld_exporter/mysqld_exporter \
--config.my-cnf=/usr/local/mysqld_exporter/.my.cnf \
--web.listen-address=:9104
Restart=always
[Install]
WantedBy=multi-user.target
systemctl daemon-reload && systemctl enable --now mysqld_exporter
systemctl status mysqld_exporter
VMware 注意事项 :mysqld_exporter 与被监控库建议同机部署(连 127.0.0.1:3306),避免跨机网络抖动造成
mysql_up误报;一台虚机若跑多个 MySQL 实例(多端口),要为每个实例起独立 exporter 并指定不同--web.listen-address(9104/9105...)。采集节点注意与业务库共享 CPU,exporter 自身很轻量,但 node_exporter 的磁盘采集在 thin 置备虚机上可能略重。
四、Prometheus 配置
4.1 采集目标
# prometheus.yml 片段
scrape_configs:
- job_name: 'mysql'
static_configs:
- targets:
- '192.168.10.51:9104' # 主库
- '192.168.10.52:9104' # 从1
- '192.168.10.53:9104' # 从2
labels:
env: 'prod'
- job_name: 'node'
static_configs:
- targets:
- '192.168.10.51:9100'
- '192.168.10.52:9100'
4.2 告警规则
groups:
- name: mysql_alerts
rules:
- alert: MySQLDown
expr: mysql_up == 0
for: 1m
labels: { severity: P0 }
annotations:
summary: "MySQL 实例不可用 ({{ $labels.instance }})"
- alert: MySQLConnectionsHigh
expr: mysql_global_status_threads_connected / mysql_global_variables_max_connections > 0.8
for: 5m
labels: { severity: P1 }
annotations:
summary: "连接数超过上限 80%"
- alert: MySQLSlaveLag
expr: mysql_slave_status_seconds_behind_master > 60
for: 2m
labels: { severity: P1 }
annotations:
summary: "主从延迟超过 60 秒"
- alert: MySQLSlaveIOThreadDown
expr: mysql_slave_status_slave_io_running == 0
for: 1m
labels: { severity: P0 }
annotations:
summary: "从库 IO 线程异常"
4.3 常用 PromQL
mysql_up # 实例存活
mysql_global_status_threads_connected # 当前连接数
rate(mysql_global_status_questions[5m]) # QPS
rate(mysql_global_status_slow_queries[5m]) # 慢查询速率
# Buffer Pool 命中率(解释:1 - 物理读/逻辑读)
1 - rate(mysql_global_status_innodb_buffer_pool_reads[5m])
/ rate(mysql_global_status_innodb_buffer_pool_read_requests[5m])
mysql_slave_status_seconds_behind_master # 主从延迟
rate(mysql_global_status_aborted_connects[5m]) # 连接失败突增
五、Grafana 看板

图 5
看板落地:① Grafana(http://grafana:3000)添加 Prometheus 数据源;② 导入社区看板 ID 7362(mysqld_exporter 官方推荐 MySQL Overview) 或 14057 ;③ 变量按
instance下拉切换实例。总览一屏:mysql_up、QPS、连接数、命中率、复制延迟、慢查询。
六、MGR/从库专属监控

图 6
# 主从延迟(对标 Oracle DG apply lag)
mysql_slave_status_seconds_behind_master > 60
# MGR 成员状态(对标 RAC 节点状态)
# 需配合 performance_schema 采集:组成员 ONLINE 比例
count by (instance) (mysql_up)
与 Oracle 17 的 RAC/DG 监控同构:Oracle 用
oracle_dg_apply_lag_seconds,MySQL 用mysql_slave_status_seconds_behind_master;Oracle 用oracle_dg_gap_status,MySQL 用mysql_slave_status_slave_io_running判断复制是否中断。
七、要点速记
- 端口牢记:mysqld_exporter 9104、node_exporter 9100、Prometheus 9090、Grafana 3000、Alertmanager 9093。
- 核心指标 :
mysql_up、threads_connected/max_connections、slow_queries、Buffer 命中率、seconds_behind_master。 - 与 Oracle 看板几乎同构 :把
oracle_前缀换成mysql_即可整体迁移。 - exporter 与库同机部署,多实例多端口、多起几个 exporter。
- 告警第一优先 :
mysql_up=0P0、从库线程中断 P0、主从延迟 P1。
八、踩坑记录(实测汇总)
| # | 坑 | 现象 | 解决 |
|---|---|---|---|
| 1 | 监控账号权限不足 | mysql_up=0 或指标为空 |
授 PROCESS/REPLICATION CLIENT/SELECT |
| 2 | 密码写命令行 | 泄露/特殊字符报错 | 用 .my.cnf 传 DSN |
| 3 | 端口冲突 | 多实例起不来 | 每实例独立 9104/9105 端口 |
| 4 | Prometheus 没接 target | 看板无数据 | 检查 scrape 目标与 9104 连通 |
| 5 | exporter 跨机连库 | 网络抖动误报 mysql_up | 同机部署连 127.0.0.1 |
| 6 | 5.7 从库指标名差异 | 无 slave 指标 | 5.7 为 mysql_slave_status_* 旧名(io_running/slave_sql_running) |
| 7 | Buffer 命中率算反 | 误判健康 | 1 - reads/read_requests |
| 8 | 没装 node_exporter | 看不到主机磁盘/CPU | 主机层与 DB 层一起采 |
| 9 | 告警风暴 | 刷屏 | Alertmanager 分组收敛(第19篇) |
| 10 | thin 置备磁盘 | node_exporter 磁盘指标抖动 | 业务库厚置备/SSD |
九、参考资料(官方正式文档)
| 主题 | 官方链接 |
|---|---|
| mysqld_exporter(GitHub) | https://github.com/prometheus/mysqld_exporter |
| Prometheus 官方文档 | https://prometheus.io/docs/ |
| Prometheus 告警规则 | https://prometheus.io/docs/prometheus/latest/configuration/alerting_rules/ |
| Grafana 官方文档 | https://grafana.com/docs/ |
| Grafana MySQL 看板库 | https://grafana.com/grafana/dashboards/7362 |
| MySQL 8.0 Status Variables | https://dev.mysql.com/doc/refman/8.0/en/server-status-variables.html |
本文章属于《MySQL 数据库全栈运维实战系列》监控与巡检篇。欢迎收藏、交流。