CentOS 7部署mysqld_exporter:MySQL指标采集、Prometheus告警与cpolar远程监控
前言
Prometheus 可以通过 Exporter 获取业务组件的内部状态,而 MySQL 并不会直接提供符合 Prometheus 采集格式的全部指标。mysqld_exporter 的作用,是连接数据库读取相应状态,再通过 HTTP /metrics 暴露数据供监控中心抓取。部署时需要明确三段链路:Exporter 能否使用监控账号登录 MySQL,Prometheus 能否访问 Exporter 监听端口,告警规则是否基于实际存在的指标正确评估。任何一段出错,都可能导致界面中有目标却没有有效数据库指标;只检查进程启动状态并不够。
本文沿用原稿的 CentOS 7 与 mysqld_exporter v0.18.0 环境,依次完成二进制下载、目录整理、MySQL 监控用户授权、客户端凭据文件、systemd 服务和 9105 指标端点配置。随后在 Prometheus 中添加静态抓取目标,加载 4.yml 告警规则,并区分 up 与 mysql_up 的含义。对于跨局域网采集,继续演示在 Exporter 所在主机安装 cpolar、生成随机公网地址及预留固定二级子域名的流程,同时给出 HTTPS 目标的配置提示。原文代码块和截图按原顺序保留,补充操作会明确标为示例;每个环节都分别说明需要验证的结果和常见失败原因,不将一次页面截图当作持续可用的证明。这是一份基于既有教程的完整部署说明,不把没有实际执行的修正步骤写成新的实测记录。

1 CentOS 7 下载并部署 mysqld_exporter v0.18.0
本篇演示采用原稿的 CentOS 7 环境,MySQL 和 Prometheus 已具备基本运行条件。mysqld_exporter 负责连接 MySQL 并暴露数据库指标;它不是数据库本身,也不负责存储时间序列。
下面先把采集端部署起来,再检查数据库登录、HTTP 指标端点和 Prometheus 抓取是否分别正常。若尚未安装 MySQL,可参考原稿所列的关联教程。
MySQL 基础安装可参考原稿提及的 cpolar 教程:《手把手教你:Centos7下MySQL的安装与初始配置》。本篇重点放在监控链路,不重复数据库初始化过程。
进入官方项目的发布页面,选择与 CPU 架构匹配的 Linux 二进制包。原文所用版本是 v0.18.0,程序名为 mysqld_exporter;下列截图保留为原稿下载页面。

如果通过浏览器下载,把压缩包上传到原稿约定的 /app 目录;后面的解压和移动命令需在压缩包所在目录执行。

也可以用原稿的 wget 示例下载。**注意:原文把 wget 和 URL 分成两行,直接作为两条命令执行无法完成下载。**原代码仍照录,后面另给可复制的单行写法。
shell
wget
https://github.com/prometheus/mysqld_exporter/releases/download/v0.18.0/mysqld_exporter-0.18.0.linux-amd64.tar.gz
**下载命令纠错:**原文代码块按原样保留。真正执行时,应把
wget与 URL 放在同一行(提前切换至/app):
shell
cd /app
wget https://github.com/prometheus/mysqld_exporter/releases/download/v0.18.0/mysqld_exporter-0.18.0.linux-amd64.tar.gz
原稿采用历史版本 0.18.0。新部署宜先查项目发行说明和目标 MySQL 版本兼容性,再决定是否使用更新版本。
压缩包准备好后,按原文命令解压。文件名中的版本和架构应与你实际下载的包一致:
shell
tar -zxvf mysqld_exporter-0.18.0.linux-amd64.tar.gz

把解压目录整理成 mysqld_exporter,以便配置 systemd 时统一引用。若当前不在 /app,需要先确认目标目录与服务中的绝对路径匹配:
shell
mv mysqld_exporter-0.18.0.linux-amd64/ mysqld_exporter

**路径检查:**原文的解压、重命名都基于压缩包已位于
/app。如在/app之外操作,后续ExecStart=/app/mysqld_exporter/mysqld_exporter将找不到文件。可先执行pwd、ls -l /app/mysqld_exporter/核对。
2 MySQL 监控用户、my.cnf 与 systemd 服务配置
为了避免使用数据库管理员账号,先创建一个供指标采集使用的专用账号。原文授权语句如下,包含演示密码 12345678;正式使用应更换强密码,并结合 MySQL 版本核对创建用户与授权语法。
shell
GRANT REPLICATION CLIENT, PROCESS ON *.* TO 'mysqld_exporter'@'localhost' identified by '12345678';
GRANT SELECT ON performance_schema.* TO 'mysqld_exporter'@'localhost';
flush privileges;

**MySQL 版本与权限提醒:**上面的
GRANT ... IDENTIFIED BY是原稿写法,并非所有 MySQL 版本都接受。MySQL 8 的常见做法是先CREATE USER、再GRANT;'localhost'账号与 TCP 连接解析也可能不完全一致。按所选 MySQL 版本和实际连接来源创建账号,并为它设置独立强密码。以下只展示账户与凭据的对应关系:
sql
-- 示例:账号名必须与下文 [client] 的 user 一致
CREATE USER 'mysqld_exporter'@'127.0.0.1' IDENTIFIED BY '请替换为独立强密码';
GRANT PROCESS, REPLICATION CLIENT ON *.* TO 'mysqld_exporter'@'127.0.0.1';
GRANT SELECT ON performance_schema.* TO 'mysqld_exporter'@'127.0.0.1';
上例以本机 IPv4 TCP 为前提;如使用 127.0.0.1 账号,请在对应服务启动参数中明确指定 --mysqld.address=127.0.0.1:3306,不要与原文默认连接地址混用。实际所需授权与 MySQL 版本、启用的采集器有关;请按官方项目说明及日志核对。
接下来准备客户端连接配置。原文 SQL 创建的是 mysqld_exporter,但下方配置却写为 exporter;两者必须一致,否则认证会失败。原始配置照录,修正示例单独给出。
shell
[client]
user=exporter
password=12345678

**账号不一致纠错:**原文 SQL 用户为
mysqld_exporter,而配置文件为exporter。下面给出与原 SQL 用户名对应的写法(密码需换成你创建用户时的真实强密码):
ini
[client]
user=mysqld_exporter
password=请填写实际设置的强密码
配置文件名称需与服务参数中的 localhost_db.cnf 对应,并确认 prometheus 用户能读取该文件。凭据文件应限制权限,不要公开到 Web 目录或提交到代码仓库。
创建 systemd 服务单元,使程序由系统统一管理。原文服务文件使用 /app/mysqld_exporter/ 与 prometheus 运行用户,并将 HTTP 监听端口设为 9105。请先确认二进制和凭据文件确实位于这些路径,再保存服务配置:
shell
[Unit]
Description=exporter
After=network.target
[Service]
Type=simple
User=prometheus
ExecStart=/app/mysqld_exporter/mysqld_exporter --config.my-cnf="/app/mysqld_exporter/localhost_db.cnf" --web.listen-address=":9105"
Restart=on-failure
[Install]
WantedBy=multi-user.target

**服务文件落地检查:**原文展示了 unit 内容,但没有完整写明保存路径。若文件存为
/etc/systemd/system/mysqld_exporter.service,需要核对prometheus系统用户存在、二进制可执行、localhost_db.cnf可读,再重新加载并启动。可以参考:
shell
sudo chmod 755 /app/mysqld_exporter/mysqld_exporter
sudo chown prometheus:prometheus /app/mysqld_exporter/localhost_db.cnf
sudo chmod 600 /app/mysqld_exporter/localhost_db.cnf
sudo systemctl daemon-reload
sudo systemctl enable --now mysqld_exporter
sudo systemctl status mysqld_exporter
若系统账号不存在,应先创建专用无交互登录账号;不能只复制 User=prometheus 就假定用户存在。
原文还给出了一条前台手动启动命令,用于不经 systemd 测试。注意它写成 /app/mysql_exporter/,与服务文件的 /app/mysqld_exporter/ 不一致。下面先保留原样供对照,随后给出统一路径的检查命令。
shell
sudo -u prometheus /app/mysql_exporter/mysqld_exporter --config.my-cnf="/app/mysql_exporter/localhost_db.cnf" --web.listen-address=":9105"
**手动调试路径提示:**原文的手动命令将目录写为
/app/mysql_exporter/,而原始mv和 unit 均为/app/mysqld_exporter/。统一路径后再尝试前台运行,并用日志或curl http://127.0.0.1:9105/metrics确认结果。避免在 systemd 已占用 9105 时同时启动第二个进程。
Exporter 启动后,访问 http://实际主机IP:9105/metrics,先确认返回指标文本。建议同时检查 mysql_up:它能反映 Exporter 最近一次尝试连接数据库是否成功;仅看到 HTTP 页面,并不能证明 MySQL 登录已成功。

3 Prometheus 静态抓取配置与指标验证
如果还没有准备好 Prometheus,可参考原稿提及的关联教程:《监控不再局域网!Cpolar 让 Prometheus 走出内网限制!》。本文假定 Prometheus 已在运行。
打开实际使用的 prometheus.yml。原文使用相对文件名,操作前应确认当前目录及 systemd 服务加载的配置路径:
shell
vi prometheus.yml
shell
- targets: ["localhost:9105"]
labels:
app: "mysql_exporter"
**抓取配置结构提示:**原文
- targets三行只是static_configs内的片段,完整任务还要有job_name。localhost:9105仅在 Prometheus 与 Exporter 位于同一网络命名空间/主机上下文时成立;若分开部署,请换成 Exporter 的实际可达地址。
yaml
# 这是单独的 scrape_configs 任务示意,不应整块覆盖现有配置
- job_name: "mysql"
metrics_path: /metrics
static_configs:
- targets: ["127.0.0.1:9105"]
labels:
app: "mysql_exporter"
改动后使用 promtool check config prometheus.yml 检查主配置。

配置保存后按原稿方式重启 Prometheus。建议先用 promtool 检查 YAML,防止缩进错误导致服务无法启动:
shell
systemctl restart prometheus
浏览器打开 Prometheus 的 9090 端口,在 Targets 页面检查新目标。

原文截图展示了目标加入监控后的状态。排查时建议分别查询 up(抓取是否成功)与 mysql_up(Exporter 是否能连接 MySQL),不要把"采集端在线"误认为"数据库健康"。

两个状态要分开看:
up == 1说明 Prometheus 最近一次成功抓取端点;mysql_up == 1才表示 Exporter 最近一次能成功连接 MySQL。若进程宕机,mysql_up这条序列可能消失,此时应通过up == 0识别抓取失败。
4 加载 4.yml 告警规则并区分采集故障
Alertmanager 的安装可参考原文关联文章:告别宕机!零基础搭建服务器监控告警系统!小白也能学会!。Prometheus 负责评估规则,Alertmanager 在配置接收器和路由后负责通知。
原稿实际给出了数据库连通性、复制延迟、复制线程、连接数和慢查询等多组规则,并非只有两个例子。下方完整保留 4.yml 的原始内容;哪些规则真正产生数据,取决于 MySQL 是否启用复制、Exporter 是否采集相应指标,以及阈值是否适合当前业务。
shell
groups:
- name: mysql-alerts
rules:
# 1. MySQL 实例宕机或 exporter 无法采集
- alert: MySQLDown
expr: mysql_up == 0
for: 1m
labels:
severity: critical
annotations:
summary: "MySQL instance down"
description: "MySQL instance {{ $labels.instance }} has been down for more than 1 minute."
# 2. 主从复制中断(仅适用于有从库的场景)
- alert: MySQLReplicationBroken
expr: mysql_slave_status_seconds_behind_master > 300
for: 2m
labels:
severity: warning
annotations:
summary: "MySQL replication lag"
description: "MySQL replication on {{ $labels.instance }} is lagging by {{ $value }} seconds."
# 3. 主从 IO/SQL 线程停止
- alert: MySQLReplicationIOThreadDown
expr: mysql_slave_status_master_server_id > 0 and mysql_slave_status_slave_io_running == 0
for: 1m
labels:
severity: critical
annotations:
summary: "MySQL replication IO thread stopped"
description: "Slave IO thread is not running on {{ $labels.instance }}."
- alert: MySQLReplicationSQLThreadDown
expr: mysql_slave_status_master_server_id > 0 and mysql_slave_status_slave_sql_running == 0
for: 1m
labels:
severity: critical
annotations:
summary: "MySQL replication SQL thread stopped"
description: "Slave SQL thread is not running on {{ $labels.instance }}."
# 4. 连接数使用率过高(超过 80%)
- alert: MySQLTooManyConnections
expr: (mysql_global_status_threads_connected / mysql_global_variables_max_connections) * 100 > 80
for: 2m
labels:
severity: warning
annotations:
summary: "High MySQL connection usage"
description: "{{ $labels.instance }}: MySQL connection usage is {{ $value | printf \"%.2f\" }}% of max_connections."
# 5. 慢查询数量突增(过去5分钟慢查询 > 10 条)
- alert: MySQLHighSlowQueries
expr: rate(mysql_global_status_slow_queries[5m]) > 0.1 # ≈ 每分钟 > 6 条
for: 5m
labels:
severity: warning
annotations:
summary: "High rate of slow queries on MySQL"
description: "{{ $labels.instance }}: Slow query rate is {{ $value | printf \"%.2f\" }} per second."
**告警规则适用性说明:**原始
mysql_up == 0不覆盖 Exporter 自身不可达;若需要检测端点故障,应另外评估up{job="mysql"} == 0。复制相关指标仅适合配置了主从复制、并实际暴露这些指标的实例。rate(...[5m]) > 0.1的单位是次/秒,相当于平均每分钟大于 6 次,不能写成"过去五分钟超过 10 条"。阈值应结合业务负载与抓取间隔调整。
promql
# 独立示意:监控端无法抓取 exporter(请替换为实际 job)
up{job="mysql"} == 0
只有 Prometheus 的 alerting 连接了 Alertmanager,且 Alertmanager 配置了接收器与路由,Firing 才可能进一步成为实际通知。

原稿将上述规则保存为 4.yml。保存后还需在 Prometheus 主配置的 rule_files 中引用该文件,才能参与规则评估。
回到 Prometheus 安装目录,找到实际运行的主配置:
编辑 prometheus.yml,核对以下规则文件路径。其中 1.yml 到 3.yml 属于原环境中已有的文件;新环境不存在这些文件时,不能机械照抄全部路径。
shell
vi prometheus.yml
shell
rule_files:
- "/app/prometheus/1.yml"
- "/app/prometheus/2.yml"
- "/app/prometheus/3.yml"
- "/app/prometheus/4.yml"
**规则校验:**原文列出的
1.yml、2.yml、3.yml如果不存在,应删除相应引用或先准备文件。新规则文件保存为/app/prometheus/4.yml后可执行:
shell
promtool check rules /app/prometheus/4.yml
promtool check config /app/prometheus/prometheus.yml
路径请按真实安装目录替换;规则中的 mysql_slave_status_* 是否存在,应在本机指标页面实际查询确认。

配置更新后,先检查规则和主配置,再按原文重启 Prometheus:
shell
systemctl restart prometheus
在浏览器打开 Prometheus 页面,查看 Rules 和 Alerts 的状态。

原文截图展示的是规则加载与告警页面。规则"可见"、表达式有结果、告警进入 Firing,以及 Alertmanager 真正向外发送通知,是四个需要分别验证的环节。

原稿通过停止 MySQL 模拟数据库不可用,展示告警触发情形。需要注意,若 Exporter 自己不可达,mysql_up 指标可能直接缺失,不能仅靠 mysql_up == 0 覆盖全部故障。

原稿展示了 MySQL 重新启动后告警恢复的页面。实际排查时应再确认数据库登录、采集端抓取与告警状态均已恢复。

到这里完成的是同一可达网络中的数据库监控。如果监控中心位于另一处网络,无法直接连接 Exporter 的 9105 端口,才需要补充跨网连通方案;无需把数据库的 3306 端口直接对外开放。
5 安装 cpolar,配置跨网络指标访问
cpolar 负责把本机服务映射为可远程访问的地址。在本篇中,转发对象是 mysqld_exporter 的 9105 指标端点,不是直接暴露 MySQL 数据库,也不是由 cpolar 代替 Prometheus 采集指标。
以下步骤应在运行 mysqld_exporter 的机器上操作:
先按原稿命令安装 cpolar。正式环境使用在线脚本前,应确认脚本来源及内容;这条命令在改写过程中没有重新执行。
shell
sudo curl https://get.cpolar.sh | sh

安装后查看 cpolar 的服务状态,确认进程正常运行:
shell
sudo systemctl status cpolar

在局域网内通过 http://运行cpolar的主机IP:9200 进入管理页面。原稿显示为 ip:9200,实际链接却指向 localhost;远程电脑不能用自己的 localhost 代替服务器地址。
用注册的 cpolar 账号登录,后续在管理页面中配置隧道。注意 9200 是 cpolar 的管理端口,9105 才是需要转发的指标服务端口。

6 映射 mysqld_exporter 的 9105 端口
在 cpolar Web UI 进入 隧道管理 → 创建隧道,根据 Exporter 的真实监听端口填写:
-
隧道名称 :例如
mysql_exporter,不要与现有隧道重名。 -
协议 :原稿选择
http。 -
本地地址 :
9105,对应 mysqld_exporter。 -
域名类型:随机域名,先用于连通性测试。
-
地区 :原稿选择
China Top,以实际界面选项为准。

创建后前往 在线隧道列表,复制当前生成的公网地址。随机地址应以你自己的列表为准,不能沿用他人的演示地址。

原稿展示了公网访问成功的截图。进一步建议检查 /metrics 返回和 Prometheus 连续抓取状态,仅打开根页面还不能说明数据库指标已经进入监控中心。

7 配置 Prometheus 公网抓取目标与 HTTPS 协议
原稿使用的公网域名示例是 38c53143.r2.cpolar.top。下方静态目标片段保持原样;配置时应按实际 URL 区分 HTTP/HTTPS、域名及端口。它表示跨网抓取 mysqld_exporter,不应误写成远程连接 MySQL 3306。
shell
- targets: ["38c53143.r2.cpolar.top"]
labels:
app: "mysql_exporter"
**公网 HTTPS 抓取示例:**原文只有
targets片段,缺少公网 URL 的协议。若 cpolar 在线隧道列表给出的是 HTTPS 地址,应设置scheme: https,目标中不要带https://,有非默认端口时要补端口。
yaml
- job_name: "mysql_public"
scheme: https
metrics_path: /metrics
static_configs:
- targets: ["你的实际公网域名"]
labels:
app: "mysql_exporter"
如果隧道或代理设置了额外认证,Prometheus 也需要匹配的认证配置。指标可能暴露数据库运行信息,不要把 9105 当作面向任何访客的公开页面 。优先采用受限网络或访问控制,TLS 传输加密不等于拥有应用层鉴权。

原文截图给出了远程目标的抓取结果。正式验证应在监控端检查 Targets、up、mysql_up 及持续抓取情况,而不是只测试某一次页面能打开。

8 预留固定二级子域名并更新抓取任务
随机域名用于初次测试较方便,但地址变化后需要同步改 Prometheus 的目标。固定二级子域名可减少频繁修改配置;它不保证 Exporter、MySQL 或隧道永远在线。

登录 cpolar 控制台,进入 预留 → 保留二级子域名 ,选定地区后填写名称。原稿示例为 mysqll,实际使用时请以自己成功预留的结果为准。

回到本地管理界面的 隧道管理 → 隧道列表 ,找到 mysql_exporter 隧道并点击 编辑。

把刚才保留成功的二级子域名关联到现有隧道:
- 域名类型:选择二级子域名。
- Sub Domain:填写已预留的子域名。
- 地区:与预留记录一致。
核对后点击 更新。

到 在线隧道列表 检查公网地址是否已替换为固定二级子域名;若之前的 Prometheus 任务仍用随机域名,还要同步更新。

再从网络另一端验证 https://实际固定域名/metrics(若你采用 HTTPS 地址),并检查监控任务的 scheme。域名固定不等于已启用身份认证。

固定域名替换完成后,别忘了更新 Prometheus 的静态目标。建议再次检查
/metrics、up与mysql_up,并确认固定地址的地区、协议和访问限制与隧道一致。
到这里,原稿所演示的本机采集、Prometheus 接入与跨网络抓取流程都有了相应操作路径。
结尾
本教程完整梳理了 mysqld_exporter、MySQL、Prometheus 和 cpolar 之间的配置关系:MySQL 用户授权与客户端凭据一致,Exporter 通过 9105 提供 /metrics,Prometheus 按正确协议抓取,4.yml 再基于存在的指标执行规则评估。部署后应同时检查 up、mysql_up、规则状态和 Alertmanager 通知结果,不能用单次访问截图代替持续采集验证。对于正式生产环境,应采用受维护的操作系统与软件版本、保护凭据及公网端点,并定期验证配置和告警链路。