前言
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. 这份脚本准备自动完成什么
现有流程把部署拆成五件事:
- 创建 MySQL 专用监控用户;
- 下载并解压 mysqld_exporter;
- 生成数据库认证文件;
- 创建 systemd 服务;
- 启动服务并提供指标地址。
脚本里还固定了几个关键参数:
- 版本:
v0.18.0 - 安装目录:
/app/mysqld_exporter - 指标端口:
9105 - 服务用户:
prometheus - MySQL 监控用户:
mysqld_exporter
这样做的意义不只是“少敲几条命令”,更重要的是让每台机器的安装结构尽量保持一致。
3. 先看完整 Shell 脚本
完整脚本如下:
1#!/bin/bash 2# 一键安装 mysqld_exporter for CentOS 7 3# 使用固定 MySQL root密码自动建用户 4# 监控用户: mysqld_exporter / Sjixin520! 5 6set -e 7 8VERSION="v0.18.0" 9INSTALL_DIR="/app/mysqld_exporter" 10PORT="9105" 11 12MYSQL_ROOT_USER="root" 13MYSQL_ROOT_PASS="Sjixin52!" 14EXPORTER_USER="mysqld_exporter" 15EXPORTER_PASS="Sjixin52!" 16 17RED='\033[0;31m' 18GREEN='\033[0;32m' 19NC='\033[0m' 20 21log() { echo -e "${GREEN}[INFO]${NC} $1"; } 22error() { echo -e "${RED}[ERROR]${NC} $1" >&2; exit 1; } 23 24if [ "$EUID" -ne 0 ]; then 25 error "请以 root 用户运行此脚本!" 26fi 27 28# 安装依赖 29log "安装必要工具..." 30yum install -y wget tar &>/dev/null 31 32# 下载mysqld_exporter 33URL="https://github.com/prometheus/mysqld_exporter/releases/download/${VERSION}/mysqld_exporter-${VERSION#v}.linux-amd64.tar.gz" 34log "正在下载mysqld_exporter ${VERSION} ..." 35wget -O /tmp/mysqld_exporter.tar.gz "$URL" || error "下载失败" 36 37# 解压到/app/mysqld_exporter 38mkdir -p "$INSTALL_DIR" 39tar -zxvf /tmp/mysqld_exporter.tar.gz -C "$INSTALL_DIR" --strip-components=1 40chown -R root:root "$INSTALL_DIR" 41 42# 确保prometheus用户存在 43if ! id "prometheus" &>/dev/null; then 44 log "创建prometheus系统用户..." 45 useradd --system --shell /sbin/nologin --no-create-home prometheus 46fi 47 48# 自动创建MySQL监控用户 49log "正在连接MySQL并创建监控用户 '$EXPORTER_USER' ..." 50 51# 测试root登录是否成功 52if ! mysql -u"$MYSQL_ROOT_USER" -p"$MYSQL_ROOT_PASS" -e "SELECT 1;" >/dev/null 2>&1; then 53 error "无法使用root / Sjixin52! 登录MySQL,请确认MySQL正在运行且密码正确" 54fi 55 56# 创建exporter用户 57mysql -u"$MYSQL_ROOT_USER" -p"$MYSQL_ROOT_PASS" <<SQL 58CREATE USER IF NOT EXISTS '$EXPORTER_USER'@'localhost' IDENTIFIED BY '$EXPORTER_PASS'; 59GRANT REPLICATION CLIENT, PROCESS ON *.* TO '$EXPORTER_USER'@'localhost'; 60GRANT SELECT ON performance_schema.* TO '$EXPORTER_USER'@'localhost'; 61FLUSH PRIVILEGES; 62SQL 63 64log "MySQL监控用户创建成功!" 65 66# 创建.my.cnf文件 67cat > "$INSTALL_DIR/localhost_db.cnf" <<EOF 68[client] 69user=$EXPORTER_USER 70password=$EXPORTER_PASS 71host=localhost 72EOF 73 74chmod 600 "$INSTALL_DIR/localhost_db.cnf" 75chown prometheus:prometheus "$INSTALL_DIR/localhost_db.cnf" 76 77# 创建systemd服务 78cat > /etc/systemd/system/mysqld_exporter.service <<EOF 79[Unit] 80Description=MySQL Exporter 81After=network.target 82 83[Service] 84Type=simple 85User=prometheus 86ExecStart=$INSTALL_DIR/mysqld_exporter \\ 87 --config.my-cnf=$INSTALL_DIR/localhost_db.cnf \\ 88 --web.listen-address=:9105 89Restart=on-failure 90RestartSec=10 91StandardOutput=journal 92StandardError=journal 93 94[Install] 95WantedBy=multi-user.target 96EOF 97 98# 启动服务 99log "启动 mysqld_exporter 服务..." 100systemctl daemon-reload 101systemctl enable --now mysqld_exporter 102 103log "✅ 安装完成!" 104log "指标地址: http://$(hostname -I | awk '{print $1}'):${PORT}/metrics" 105log "服务状态: systemctl status mysqld_exporter" 106
这份脚本里几个关键动作值得单独看一下。
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. 把脚本保存下来并实际执行
先创建脚本文件:
1vi mysql_exporter.sh 2
然后把完整内容写进去:
1#!/bin/bash 2# 一键安装 mysqld_exporter for CentOS 7 3# 使用固定 MySQL root密码自动建用户 4# 监控用户: mysqld_exporter / Sjixin520! 5 6set -e 7 8VERSION="v0.18.0" 9INSTALL_DIR="/app/mysqld_exporter" 10PORT="9105" 11 12MYSQL_ROOT_USER="root" 13MYSQL_ROOT_PASS="Sjixin52!" 14EXPORTER_USER="mysqld_exporter" 15EXPORTER_PASS="Sjixin52!" 16 17RED='\033[0;31m' 18GREEN='\033[0;32m' 19NC='\033[0m' 20 21log() { echo -e "${GREEN}[INFO]${NC} $1"; } 22error() { echo -e "${RED}[ERROR]${NC} $1" >&2; exit 1; } 23 24if [ "$EUID" -ne 0 ]; then 25 error "请以 root 用户运行此脚本!" 26fi 27 28# 安装依赖 29log "安装必要工具..." 30yum install -y wget tar &>/dev/null 31 32# 下载mysqld_exporter 33URL="https://github.com/prometheus/mysqld_exporter/releases/download/${VERSION}/mysqld_exporter-${VERSION#v}.linux-amd64.tar.gz" 34log "正在下载mysqld_exporter ${VERSION} ..." 35wget -O /tmp/mysqld_exporter.tar.gz "$URL" || error "下载失败" 36 37# 解压到/app/mysqld_exporter 38mkdir -p "$INSTALL_DIR" 39tar -zxvf /tmp/mysqld_exporter.tar.gz -C "$INSTALL_DIR" --strip-components=1 40chown -R root:root "$INSTALL_DIR" 41 42# 确保prometheus用户存在 43if ! id "prometheus" &>/dev/null; then 44 log "创建prometheus系统用户..." 45 useradd --system --shell /sbin/nologin --no-create-home prometheus 46fi 47 48# 自动创建MySQL监控用户 49log "正在连接MySQL并创建监控用户 '$EXPORTER_USER' ..." 50 51# 测试root登录是否成功 52if ! mysql -u"$MYSQL_ROOT_USER" -p"$MYSQL_ROOT_PASS" -e "SELECT 1;" >/dev/null 2>&1; then 53 error "无法使用root / Sjixin52! 登录MySQL,请确认MySQL正在运行且密码正确" 54fi 55 56# 创建exporter用户 57mysql -u"$MYSQL_ROOT_USER" -p"$MYSQL_ROOT_PASS" <<SQL 58CREATE USER IF NOT EXISTS '$EXPORTER_USER'@'localhost' IDENTIFIED BY '$EXPORTER_PASS'; 59GRANT REPLICATION CLIENT, PROCESS ON *.* TO '$EXPORTER_USER'@'localhost'; 60GRANT SELECT ON performance_schema.* TO '$EXPORTER_USER'@'localhost'; 61FLUSH PRIVILEGES; 62SQL 63 64log "MySQL监控用户创建成功!" 65 66# 创建.my.cnf文件 67cat > "$INSTALL_DIR/localhost_db.cnf" <<EOF 68[client] 69user=$EXPORTER_USER 70password=$EXPORTER_PASS 71host=localhost 72EOF 73 74chmod 600 "$INSTALL_DIR/localhost_db.cnf" 75chown prometheus:prometheus "$INSTALL_DIR/localhost_db.cnf" 76 77# 创建systemd服务 78cat > /etc/systemd/system/mysqld_exporter.service <<EOF 79[Unit] 80Description=MySQL Exporter 81After=network.target 82 83[Service] 84Type=simple 85User=prometheus 86ExecStart=$INSTALL_DIR/mysqld_exporter \\ 87 --config.my-cnf=$INSTALL_DIR/localhost_db.cnf \\ 88 --web.listen-address=:9105 89Restart=on-failure 90RestartSec=10 91StandardOutput=journal 92StandardError=journal 93 94[Install] 95WantedBy=multi-user.target 96EOF 97 98# 启动服务 99log "启动 mysqld_exporter 服务..." 100systemctl daemon-reload 101systemctl enable --now mysqld_exporter 102 103log "✅ 安装完成!" 104log "指标地址: http://$(hostname -I | awk '{print $1}'):${PORT}/metrics" 105log "服务状态: systemctl status mysqld_exporter" 106

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

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

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

这里的 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
执行安装:
1sudo curl https://get.cpolar.sh | sh 2

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

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

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

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

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

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 批量执行,会比每台服务器手工安装更容易维护。
《mysqld_exporter自动化监控链:Shell安装、systemd托管与Prometheus抓取》 是转载文章,点击查看原文。