云计算百科
云计算领域专业知识百科平台

mysqld_exporter自动化监控链:Shell安装、systemd托管与Prometheus抓取

前言

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 里配置抓取。

image-20260114172313119

机器一多以后,最怕的不是慢,而是不一致。

这台装在 /app/mysqld_exporter,下一台路径换了;这台端口是 9105,另一台配置文件又放到了别处。等后面批量维护时,这些小差异最容易变成排错成本。

所以这篇的核心思路就是:把路径、账号、端口、权限和服务注册一次写进脚本,后面重复执行。

2. 这份脚本准备自动完成什么

现有流程把部署拆成五件事:

  • 创建 MySQL 专用监控用户;
  • 下载并解压 mysqld_exporter;
  • 生成数据库认证文件;
  • 创建 systemd 服务;
  • 启动服务并提供指标地址。
  • 脚本里还固定了几个关键参数:

    • 版本: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"

    8c2d5c1922260fb9743f2a1e23afffc7

    保存以后直接执行:

    sh mysql_exporter.sh

    623449c6efa42fc2459e175cb3509812

    这里我更关心的不是终端里有没有出现“安装完成”,而是服务是不是已经真的被 systemd 接管。

    所以继续检查:

    systemctl status mysqld_exporter

    02f1d5357ec20d6667854d1cc18d1960

    服务状态正常以后,才说明这份自动化脚本真正把下载、账号、配置和服务注册这一整条链跑通了。

    5. 接入 Prometheus

    mysqld_exporter 本身只是暴露指标。

    真正进入监控体系,还需要 Prometheus 去抓它。

    编辑 Prometheus 配置:

    vi prometheus.yml

    加入当前示例里的抓取目标:

    – targets: ["192.168.42.146:9105"]
    labels:
    app: "mysql_exporter"

    image-20260116144251013

    这里的 exporter 地址是:

    192.168.42.146:9105

    配置完成以后,从浏览器打开 Prometheus 页面:

    image-20260116145725079

    可以看到 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

    image-20250814101639846

    安装完成以后检查服务状态:

    sudo systemctl status cpolar

    22e5adfaf290a17fc3384bb296055259

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

    8a6698b1bf26d64ba3645827fbfb1c29

    到这里,远程网络入口工具已经准备完成。

    8. 给 mysqld_exporter 的 9105 创建外部访问地址

    创建隧道时,当前参数为:

    • 隧道名称:mysql_exporter
    • 协议:http
    • 本地地址:9105
    • 域名类型:随机域名
    • 地区:China Top

    image-20251125140431855

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

    image-20251125140532931

    当前示例给出的公网地址是:

    38c53143.r2.cpolar.top

    接着把 Prometheus 抓取目标改成:

    – targets: ["38c53143.r2.cpolar.top"]
    labels:
    app: "mysql_exporter"

    image-20251125140712345

    Prometheus 抓取成功:

    image-20251125140820943

    这一步验证的是:Prometheus 即使不在 MySQL 所在局域网,也能继续访问 exporter 暴露出来的指标服务。

    9. 长期使用再配置固定地址

    随机地址适合测试。

    如果 Prometheus 要长期抓取,目标地址经常变化显然不适合,所以继续配置固定二级子域名。

    image-20251125141035399

    进入预留页面,当前示例使用:

    • 地区:china Top
    • 二级子域名:mysqll

    image-20251125141009206

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

    image-20251125141100804

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

    image-20251125141128044

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

    image-20251125141147962

    最后访问固定地址测试:

    image-20251125141202184

    长期使用时,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 批量执行,会比每台服务器手工安装更容易维护。

    赞(0)
    未经允许不得转载:网硕互联帮助中心 » mysqld_exporter自动化监控链:Shell安装、systemd托管与Prometheus抓取
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!