mysqld_exporter是暴露MySQL指标的唯一可靠方案,需配置专用账号权限、调整Prometheus采集超时、聚焦核心指标、绑定实例标签并设置告警持续时间。

MySQL需要先暴露指标:mysqld_exporter 是唯一靠谱的选择
直接让 MySQL 自己输出 Prometheus 格式指标是不可能的——它不支持。必须靠 mysqld_exporter 这个官方推荐的中间件来抓取、转换并暴露指标。它不修改 MySQL,只用一个普通账号(PROCESS、REPLICATION CLIENT 等权限)连上去读状态变量和性能模式表。
常见错误是跳过权限配置,结果 mysqld_exporter 启动后日志里反复报 access denied 或 cannot connect。实际只需在 MySQL 里执行:
CREATE USER 'exporter'@'localhost' IDENTIFIED BY 'safe_password'; GRANT PROCESS, REPLICATION CLIENT, SELECT ON *.* TO 'exporter'@'localhost'; FLUSH PRIVILEGES;
注意:mysqld_exporter 默认监听 localhost:9104,如果 Prometheus 在另一台机器上采集,得把 'exporter'@'localhost' 改成 'exporter'@'%'(并确保网络可达),同时启动时加 --web.listen-address="0.0.0.0:9104"。
Prometheus 配置 job 要避开 scrape_timeout 和 tls_verify 陷阱
mysqld_exporter 响应一般很快,但若 MySQL 实例负载高、或启用了大量收集器(如 --collect.perf_schema.eventswaits),单次采集可能超默认 10s。这时 Prometheus 会标记为 DOWN,但日志里只显示 context deadline exceeded,容易误判为网络问题。
在 prometheus.yml 的 job 配置中,至少要调整两项:
- 把
scrape_timeout提到15s或20s(不能超过scrape_interval) - 如果 MySQL 服务器没配 TLS,而
mysqld_exporter又被误加了--web.config.file启用 HTTPS,则 Prometheus 采集会因证书验证失败静默失败;确认不用 TLS 就别碰web.config.file
最小可用 job 示例:
scrape_configs:
- job_name: 'mysql'
static_configs:
- targets: ['10.0.1.22:9104']
scrape_timeout: 15s核心指标就这五个,别一上来就开全量收集器
mysqld_exporter 默认只开基础收集器(global status、info schema),已经覆盖 90% 运维关注点。强行启用所有收集器(比如 --collect.perf_schema.tablelocks)不仅增加 MySQL 查询压力,还可能因性能模式表锁导致慢查询堆积。
Linux 安全审计工具,检查 SSH 配置、开放/监听端口、防火墙规则(ufw/iptables/nftables)、失败登录尝试、sudoers 权限...
真正该盯住的指标只有这些:
-
mysql_up:判断 exporter 是否能连上 MySQL(不是 MySQL 是否存活) -
mysql_global_status_threads_connected:当前连接数,突增往往意味着应用泄漏或攻击 -
mysql_global_status_questions:每秒 QPS,配合rate(mysql_global_status_questions[5m])看趋势 -
mysql_global_status_slow_queries:慢查总数,用delta(mysql_global_status_slow_queries[1h])算小时增量更实用 -
mysql_global_variables_max_connections对比threads_connected,算连接使用率
想查 InnoDB 缓冲池命中率?用 (1 - rate(mysql_global_status_innodb_buffer_pool_reads[5m]) / rate(mysql_global_status_innodb_buffer_pool_read_requests[5m])) * 100,别依赖第三方 dashboard 里的“黑盒公式”。
Alert 规则要绑定实例标签,否则告警根本分不清是哪个库
一台机器跑多个 MySQL 实例(比如 3306/3307)、或用 Docker 动态部署时,mysqld_exporter 默认只上报 instance="10.0.1.22:9104",告警触发后你根本不知道是主库还是从库出问题。
解决方法是在 Prometheus 的 job 配置里显式加 static_labels:
- job_name: 'mysql-prod-master'
static_configs:
- targets: ['10.0.1.22:9104']
static_labels:
mysql_role: 'master'
mysql_cluster: 'prod'然后告警规则里就能写 mysql_global_status_threads_connected{mysql_role="master"} > 500。漏掉这步,后续所有分组、静默、路由都成空谈。
另外,mysql_up == 0 类告警必须加 for: 2m,避免瞬时抖动误报——Exporter 进程重启、MySQL 短暂卡住都会触发,没人希望半夜被这种告警叫醒。

















