前言
mysqld_exporter 本身并不难安装,真正容易出问题的是部署步骤太分散:二进制文件、MySQL 监控账号、权限、认证文件、systemd 服务和 9105 指标端口都需要逐项配置。机器一多以后,手工操作很容易出现路径、账号或参数不一致。
这篇文章的重点就是把这些步骤收进一个 Shell 脚本。脚本固定使用 v0.18.0,安装到 /app/mysqld_exporter,自动准备 prometheus 系统用户,创建 MySQL 监控账号,生成 localhost_db.cnf,再注册 mysqld_exporter.service 并通过 systemd 启动。
脚本执行完成后,还会继续检查服务状态,并把 9105 加入 Prometheus 抓取目标,确认 exporter 指标已经真正进入监控链路。
如果 Prometheus 和 MySQL 不在同一网络,再继续处理远程抓取,让 Prometheus 通过外部地址访问内网中的 exporter,而不是直接暴露数据库本身。
整篇重点放在“脚本标准化—服务托管—Prometheus 抓取—跨网监控”这条链路,而不是简单重复一遍手工安装步骤。
对于这类监控组件,自动化脚本的意义不是省掉所有判断,而是把可重复的安装动作标准化。最终仍然要用 systemd 状态和 Prometheus 抓取结果验证,而不是只看脚本是否执行到最后。把部署结果和监控结果分开验证,后续批量铺开时也更容易定位问题。更稳。
1. 为什么我更愿意把 mysqld_exporter 写成脚本
手工安装一次 mysqld_exporter,其实不算难。
真正麻烦的是同样的事情要重复很多次:下载、解压、建用户、改权限、写认证文件、写 systemd、启动、设开机自启,再去 Prometheus 里配置抓取。

机器一多以后,最怕的不是慢,而是不一致。
这台装在 /app/mysqld_exporter,下一台路径换了;这台端口是 9105,另一台配置文件又放到了别处。等后面批量维护时,这些小差异最容易变成排错成本。
所以这篇的核心思路就是:把路径、账号、端口、权限和服务注册一次写进脚本,后面重复执行。
2. 这份脚本准备自动完成什么
现有流程把部署拆成五件事:
脚本里还固定了几个关键参数:
- 版本:v0.18.0
- 安装目录:/app/mysqld_exporter
- 指标端口:9105
- 服务用户:prometheus
- MySQL 监控用户:mysqld_exporter
这样做的意义不只是“少敲几条命令”,更重要的是让每台机器的安装结构尽量保持一致。
3. 先看完整 Shell 脚本
完整脚本如下:
#!/bin/bash
# 一键安装 mysqld_exporter for CentOS 7
# 使用固定 MySQL root密码自动建用户
# 监控用户: mysqld_exporter / Sjixin520!
set -e
VERSION="v0.18.0"
INSTALL_DIR="/app/mysqld_exporter"
PORT="9105"
MYSQL_ROOT_USER="root"
MYSQL_ROOT_PASS="Sjixin52!"
EXPORTER_USER="mysqld_exporter"
EXPORTER_PASS="Sjixin52!"
RED='\\033[0;31m'
GREEN='\\033[0;32m'
NC='\\033[0m'
log() { echo -e "${GREEN}[INFO]${NC} $1"; }
error() { echo -e "${RED}[ERROR]${NC} $1" >&2; exit 1; }
if [ "$EUID" -ne 0 ]; then
error "请以 root 用户运行此脚本!"
fi
# 安装依赖
log "安装必要工具…"
yum install -y wget tar &>/dev/null
# 下载mysqld_exporter
URL="https://github.com/prometheus/mysqld_exporter/releases/download/${VERSION}/mysqld_exporter-${VERSION#v}.linux-amd64.tar.gz"
log "正在下载mysqld_exporter ${VERSION} …"
wget -O /tmp/mysqld_exporter.tar.gz "$URL" || error "下载失败"
# 解压到/app/mysqld_exporter
mkdir -p "$INSTALL_DIR"
tar -zxvf /tmp/mysqld_exporter.tar.gz -C "$INSTALL_DIR" –strip-components=1
chown -R root:root "$INSTALL_DIR"
# 确保prometheus用户存在
if ! id "prometheus" &>/dev/null; then
log "创建prometheus系统用户…"
useradd –system –shell /sbin/nologin –no-create-home prometheus
fi
# 自动创建MySQL监控用户
log "正在连接MySQL并创建监控用户 '$EXPORTER_USER' …"
# 测试root登录是否成功
if ! mysql -u"$MYSQL_ROOT_USER" -p"$MYSQL_ROOT_PASS" -e "SELECT 1;" >/dev/null 2>&1; then
error "无法使用root / Sjixin52! 登录MySQL,请确认MySQL正在运行且密码正确"
fi
# 创建exporter用户
mysql -u"$MYSQL_ROOT_USER" -p"$MYSQL_ROOT_PASS" <<SQL
CREATE USER IF NOT EXISTS '$EXPORTER_USER'@'localhost' IDENTIFIED BY '$EXPORTER_PASS';
GRANT REPLICATION CLIENT, PROCESS ON *.* TO '$EXPORTER_USER'@'localhost';
GRANT SELECT ON performance_schema.* TO '$EXPORTER_USER'@'localhost';
FLUSH PRIVILEGES;
SQL
log "MySQL监控用户创建成功!"
# 创建.my.cnf文件
cat > "$INSTALL_DIR/localhost_db.cnf" <<EOF
[client]
user=$EXPORTER_USER
password=$EXPORTER_PASS
host=localhost
EOF
chmod 600 "$INSTALL_DIR/localhost_db.cnf"
chown prometheus:prometheus "$INSTALL_DIR/localhost_db.cnf"
# 创建systemd服务
cat > /etc/systemd/system/mysqld_exporter.service <<EOF
[Unit]
Description=MySQL Exporter
After=network.target
[Service]
Type=simple
User=prometheus
ExecStart=$INSTALL_DIR/mysqld_exporter \\\\
–config.my-cnf=$INSTALL_DIR/localhost_db.cnf \\\\
–web.listen-address=:9105
Restart=on-failure
RestartSec=10
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
EOF
# 启动服务
log "启动 mysqld_exporter 服务…"
systemctl daemon-reload
systemctl enable –now mysqld_exporter
log "✅ 安装完成!"
log "指标地址: http://$(hostname -I | awk '{print $1}'):${PORT}/metrics"
log "服务状态: systemctl status mysqld_exporter"
这份脚本里几个关键动作值得单独看一下。
3.1 先检查 root 权限
脚本会检查当前是否以 root 身份运行。
如果不是 root,就直接退出,不继续往下执行。
3.2 自动安装基础工具
脚本使用 yum 安装 wget 和 tar,避免后面下载、解压阶段才发现基础命令不存在。
3.3 自动下载指定版本
下载地址根据:
VERSION="v0.18.0"
自动拼接。
二进制文件最终放到:
/app/mysqld_exporter
这样后面 systemd 和配置文件都能继续引用同一套固定路径。
3.4 自动准备 prometheus 用户
如果系统中没有 prometheus 用户,脚本会自动创建一个不能登录的系统用户。
mysqld_exporter 最终也通过这个用户运行,而不是直接使用 root。
3.5 自动创建 MySQL 监控账号
脚本会先测试 MySQL root 登录,然后创建:
mysqld_exporter@localhost
并授予当前脚本里定义的监控权限。
这一步如果失败,脚本会直接停止,不继续创建后面的服务。
3.6 自动生成认证文件
认证文件保存为:
/app/mysqld_exporter/localhost_db.cnf
里面包含 [client]、用户名、密码和 localhost。
脚本随后把权限设为 600,并把文件属主改成 prometheus。
3.7 自动注册 systemd
服务文件写入:
/etc/systemd/system/mysqld_exporter.service
启动参数里指定认证文件和 9105 监听端口。
最后执行 systemctl daemon-reload 和 systemctl enable –now mysqld_exporter。
也就是说,安装、启动和开机自启一次完成。
4. 把脚本保存下来并实际执行
先创建脚本文件:
vi mysql_exporter.sh
然后把完整内容写进去:
#!/bin/bash
# 一键安装 mysqld_exporter for CentOS 7
# 使用固定 MySQL root密码自动建用户
# 监控用户: mysqld_exporter / Sjixin520!
set -e
VERSION="v0.18.0"
INSTALL_DIR="/app/mysqld_exporter"
PORT="9105"
MYSQL_ROOT_USER="root"
MYSQL_ROOT_PASS="Sjixin52!"
EXPORTER_USER="mysqld_exporter"
EXPORTER_PASS="Sjixin52!"
RED='\\033[0;31m'
GREEN='\\033[0;32m'
NC='\\033[0m'
log() { echo -e "${GREEN}[INFO]${NC} $1"; }
error() { echo -e "${RED}[ERROR]${NC} $1" >&2; exit 1; }
if [ "$EUID" -ne 0 ]; then
error "请以 root 用户运行此脚本!"
fi
# 安装依赖
log "安装必要工具…"
yum install -y wget tar &>/dev/null
# 下载mysqld_exporter
URL="https://github.com/prometheus/mysqld_exporter/releases/download/${VERSION}/mysqld_exporter-${VERSION#v}.linux-amd64.tar.gz"
log "正在下载mysqld_exporter ${VERSION} …"
wget -O /tmp/mysqld_exporter.tar.gz "$URL" || error "下载失败"
# 解压到/app/mysqld_exporter
mkdir -p "$INSTALL_DIR"
tar -zxvf /tmp/mysqld_exporter.tar.gz -C "$INSTALL_DIR" –strip-components=1
chown -R root:root "$INSTALL_DIR"
# 确保prometheus用户存在
if ! id "prometheus" &>/dev/null; then
log "创建prometheus系统用户…"
useradd –system –shell /sbin/nologin –no-create-home prometheus
fi
# 自动创建MySQL监控用户
log "正在连接MySQL并创建监控用户 '$EXPORTER_USER' …"
# 测试root登录是否成功
if ! mysql -u"$MYSQL_ROOT_USER" -p"$MYSQL_ROOT_PASS" -e "SELECT 1;" >/dev/null 2>&1; then
error "无法使用root / Sjixin52! 登录MySQL,请确认MySQL正在运行且密码正确"
fi
# 创建exporter用户
mysql -u"$MYSQL_ROOT_USER" -p"$MYSQL_ROOT_PASS" <<SQL
CREATE USER IF NOT EXISTS '$EXPORTER_USER'@'localhost' IDENTIFIED BY '$EXPORTER_PASS';
GRANT REPLICATION CLIENT, PROCESS ON *.* TO '$EXPORTER_USER'@'localhost';
GRANT SELECT ON performance_schema.* TO '$EXPORTER_USER'@'localhost';
FLUSH PRIVILEGES;
SQL
log "MySQL监控用户创建成功!"
# 创建.my.cnf文件
cat > "$INSTALL_DIR/localhost_db.cnf" <<EOF
[client]
user=$EXPORTER_USER
password=$EXPORTER_PASS
host=localhost
EOF
chmod 600 "$INSTALL_DIR/localhost_db.cnf"
chown prometheus:prometheus "$INSTALL_DIR/localhost_db.cnf"
# 创建systemd服务
cat > /etc/systemd/system/mysqld_exporter.service <<EOF
[Unit]
Description=MySQL Exporter
After=network.target
[Service]
Type=simple
User=prometheus
ExecStart=$INSTALL_DIR/mysqld_exporter \\\\
–config.my-cnf=$INSTALL_DIR/localhost_db.cnf \\\\
–web.listen-address=:9105
Restart=on-failure
RestartSec=10
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
EOF
# 启动服务
log "启动 mysqld_exporter 服务…"
systemctl daemon-reload
systemctl enable –now mysqld_exporter
log "✅ 安装完成!"
log "指标地址: http://$(hostname -I | awk '{print $1}'):${PORT}/metrics"
log "服务状态: systemctl status mysqld_exporter"

保存以后直接执行:
sh mysql_exporter.sh

这里我更关心的不是终端里有没有出现“安装完成”,而是服务是不是已经真的被 systemd 接管。
所以继续检查:
systemctl status mysqld_exporter

服务状态正常以后,才说明这份自动化脚本真正把下载、账号、配置和服务注册这一整条链跑通了。
5. 接入 Prometheus
mysqld_exporter 本身只是暴露指标。
真正进入监控体系,还需要 Prometheus 去抓它。
编辑 Prometheus 配置:
vi prometheus.yml
加入当前示例里的抓取目标:
– targets: ["192.168.42.146:9105"]
labels:
app: "mysql_exporter"

这里的 exporter 地址是:
192.168.42.146:9105
配置完成以后,从浏览器打开 Prometheus 页面:

可以看到 Prometheus 已经抓取到这台主机上的 mysqld_exporter。
做到这里,第一条完整链路成立:
MySQL → mysqld_exporter → 9105 → Prometheus。
6. 如果 Prometheus 和 MySQL 不在同一个网络
同一个局域网里,Prometheus 直接抓 IP:9105 最简单。
但如果 Prometheus 在另一张网络里,而 mysqld_exporter 跑在内网主机上,内网地址就不能直接访问。
这里要解决的是 Prometheus 到 exporter 的网络可达性,而不是让 Prometheus 直接连接 MySQL 数据库。
后面的方案是把已经运行在 9105 的指标服务提供一个外部入口。
7. 安装 cpolar
执行安装:
sudo curl https://get.cpolar.sh | sh

安装完成以后检查服务状态:
sudo systemctl status cpolar

然后通过 9200 端口进入 Web 管理界面:

到这里,远程网络入口工具已经准备完成。
8. 给 mysqld_exporter 的 9105 创建外部访问地址
创建隧道时,当前参数为:
- 隧道名称:mysql_exporter
- 协议:http
- 本地地址:9105
- 域名类型:随机域名
- 地区:China Top

创建以后,在在线隧道列表查看地址:

当前示例给出的公网地址是:
38c53143.r2.cpolar.top
接着把 Prometheus 抓取目标改成:
– targets: ["38c53143.r2.cpolar.top"]
labels:
app: "mysql_exporter"

Prometheus 抓取成功:

这一步验证的是:Prometheus 即使不在 MySQL 所在局域网,也能继续访问 exporter 暴露出来的指标服务。
9. 长期使用再配置固定地址
随机地址适合测试。
如果 Prometheus 要长期抓取,目标地址经常变化显然不适合,所以继续配置固定二级子域名。

进入预留页面,当前示例使用:
- 地区:china Top
- 二级子域名:mysqll

然后回到隧道列表,找到 mysql_exporter:

编辑隧道,把域名类型改成二级子域名:

更新完成后,再查看在线隧道:

最后访问固定地址测试:

长期使用时,Prometheus 的 target 也应该对应这个稳定地址,避免随机域名变化以后抓取中断。
10. 这份脚本真正适合什么场景
如果只有一台机器,手动安装 mysqld_exporter 完全可以。
脚本真正开始有价值,是在这些场景里:
- 多台 MySQL 主机需要统一部署 exporter;
- 希望安装路径和端口保持一致;
- 不想每次重新创建 systemd;
- 希望监控账号和认证文件生成方式统一;
- 后续还准备通过 Ansible 或 SSH 批量执行。
对我来说,自动化的价值不是“一条命令显得很酷”,而是同样的环境和同样的任务以后可以稳定重复。
总结
整套流程可以拆成四层:Shell 脚本负责标准化安装,systemd 负责长期托管 mysqld_exporter,9105 提供指标接口,Prometheus 负责实际抓取。
脚本执行完成以后,还要继续检查 mysqld_exporter 服务状态,并把 exporter 加入 Prometheus target。只有 Prometheus 真正抓到指标,才能说明监控链路已经闭环,而不是单纯服务启动成功。
跨网络场景下,再给 9105 增加外部访问入口,并根据长期使用需求配置固定地址。这样可以把网络问题和 exporter 本身的安装、认证、systemd 问题分开处理。
对于多主机环境来说,这类脚本最大的价值是统一版本、路径、端口和服务管理方式。后续再配合 Ansible、SSH 批量执行,会比每台服务器手工安装更容易维护。
网硕互联帮助中心





评论前必须登录!
注册