Prometheus 监控 MySQL 搭建与维护文档
适用环境:node2 (192.168.56.132)・RHEL 8.6 (Ootpa)
整理日期:2026-10-10
文档性质:MySQL 监控全流程搭建实录 + 维护手册
1. 监控架构总览
MySQL (3306) ──► mysqld_exporter (9104) ──► Prometheus (9090) ──► Grafana (3000)
数据库源 采集(专用账号) 存储TSDB(15天) 可视化展示
-
MySQL 8.4.8:数据源,监听 3306(X Protocol 33060)。
-
mysqld_exporter 0.17.2:通过专用账号连库采集指标,监听 9104。
-
Prometheus 3.11.2:按 5s 周期抓取 9104,写入
/var/lib/prometheusTSDB。 -
Grafana 6.0.1:已配 Prometheus 数据源(默认),展示 MySQL 面板。
2. 环境现状(搭建前探查结论)
| 项 | 现状 |
|---|---|
| 主机 / IP | node2 / 192.168.56.132 |
| 操作系统 | RHEL 8.6 |
| MySQL | 已安装 mysql-community-server-8.4.8,未初始化 / 未启动 |
| mysqld_exporter | 未安装(9104 无监听) |
| Prometheus | active,9090,已有 postgresql job |
| Grafana | 手动运行,3000,已有 Prometheus 数据源 |
| 遗留配置 | /etc/my.cnf 含一套 mysqld_multi 多实例 (3306/3307) 配置,用户要求保留 |
⚠️ 关键约束:
/etc/my.cnf被多实例配置占用,且其指向的
/usr/local/mysql/bin/mysqld二进制不存在(是废弃残留)。为
不破坏它
,单实例 MySQL 改用
独立配置 + systemd 覆盖
方式启动。
3. 创建 MySQL 实例(详细步骤)
3.1 确认可用的 MySQL
rpm -q mysql-community-server # mysql-community-server-8.4.8-1.el8.x86_64
mysqld --version # /usr/sbin/mysqld Ver 8.4.8
ls /var/lib/mysql | grep -E 'ibdata|mysql.ibd' # 数据目录已初始化
3.2 编写独立配置文件 /etc/my_mysql.cnf(不碰 /etc/my.cnf)
[mysqld]
datadir=/var/lib/mysql
socket=/var/run/mysqld/mysqld.sock
pid-file=/var/run/mysqld/mysqld.pid
port=3306
character_set_server=utf8mb4
bind-address=0.0.0.0
skip-symbolic-links=0
3.3 systemd 覆盖,让 mysqld 用独立配置启动
创建 /etc/systemd/system/mysqld.service.d/override.conf:
[Service]
ExecStart=
ExecStart=/usr/sbin/mysqld --defaults-file=/etc/my_mysql.cnf $MYSQLD_OPTS
执行:
systemctl daemon-reload
systemctl start mysqld
systemctl status mysqld # active (running)
ss -tlnp | grep 3306 # 0.0.0.0:3306 LISTEN
3.4 重置 root 密码(原密码未知)
由于 root 密码在 history / 日志中均无记录,采用 skip-grant-tables 临时模式重置:
# 1) 停服务,临时改用 skip-grant-tables 启动
systemctl stop mysqld
# 修改 override.conf 的 ExecStart,加入 --skip-grant-tables
systemctl daemon-reload && systemctl start mysqld
# 2) 免密登录并重置密码
mysql --socket=/var/run/mysqld/mysqld.sock -uroot \
-e "FLUSH PRIVILEGES; ALTER USER 'root'@'localhost' IDENTIFIED BY 'Lihj2026'; FLUSH PRIVILEGES;"
# 3) 还原 override.conf(去掉 skip-grant-tables),恢复正常启动
systemctl daemon-reload && systemctl restart mysqld
# 4) 验证新密码登录
mysql -uroot -pLihj2026 -h127.0.0.1 -P3306 -e "SELECT VERSION();"
✅ 结果:MySQL 8.4.8 正常监听 3306/33060,root 密码 Lihj2026 生效。
4. 创建 MySQL 监控专用账号
为最小权限采集,创建 exporter 账号:
CREATE USER IF NOT EXISTS 'exporter'@'localhost' IDENTIFIED BY 'exporter_pass';
GRANT PROCESS, REPLICATION CLIENT, SELECT ON *.* TO 'exporter'@'localhost';
CREATE USER IF NOT EXISTS 'exporter'@'127.0.0.1' IDENTIFIED BY 'exporter_pass';
GRANT PROCESS, REPLICATION CLIENT, SELECT ON *.* TO 'exporter'@'127.0.0.1';
FLUSH PRIVILEGES;
验证:
mysql -uexporter -pexporter_pass -h127.0.0.1 -e "SHOW GRANTS;"
# GRANT SELECT, PROCESS, REPLICATION CLIENT ON *.* TO `exporter`@`127.0.0.1`
✅ 结果:监控账号可用,权限仅 SELECT / PROCESS / REPLICATION CLIENT。
5. 安装并配置 mysqld_exporter(详细步骤)
5.1 下载二进制(GitHub 直连失败,用代理源)
服务器直连 GitHub 报 SSL_ERROR_SYSCALL errno 104,改用国内代理源 ghfast.top 成功:
cd /tmp
curl -L --max-time 120 -o mysqld_exporter.tar.gz \
'https://ghfast.top/https://github.com/prometheus/mysqld_exporter/releases/download/v0.17.2/mysqld_exporter-0.17.2.linux-amd64.tar.gz'
tar xzf mysqld_exporter.tar.gz
cp mysqld_exporter-0.17.2.linux-amd64/mysqld_exporter /usr/local/bin/mysqld_exporter
chmod 755 /usr/local/bin/mysqld_exporter
/usr/local/bin/mysqld_exporter --version # mysqld_exporter, version 0.17.2
其他可用代理源(本次探测):
gh-proxy.com、
ghfast.top(HTTP 200);
mirror.ghproxy.com、
download.fastgit.org不可用。
5.2 编写连接配置 /root/.my.cnf
[client]
user=exporter
password=exporter_pass
host=127.0.0.1
port=3306
权限需 chmod 600。
5.3 编写 systemd 服务 /etc/systemd/system/mysqld-exporter.service
[Unit]
Description=MySQL Exporter
After=network.target
[Service]
Type=simple
User=root
Environment="DATA_SOURCE_NAME=exporter:exporter_pass@tcp(127.0.0.1:3306)/"
ExecStart=/usr/local/bin/mysqld_exporter --web.listen-address=:9104 --config.my-cnf=/root/.my.cnf
Restart=always
[Install]
WantedBy=multi-user.target
5.4 启动并验证
systemctl daemon-reload
systemctl start mysqld-exporter
systemctl status mysqld-exporter # active (running)
ss -tlnp | grep 9104 # *:9104 LISTEN
curl -s http://127.0.0.1:9104/metrics | grep -E '^mysql_up|^mysql_global_status_uptime'
# mysql_up 1
# mysql_global_status_uptime 488
✅ 结果:exporter 运行,mysql_up=1,指标正常采集。
6. 增加 Prometheus 抓取(详细步骤)
6.1 备份并修改 /etc/prometheus/prometheus.yml
在 scrape_configs: 末尾新增 job(保留原 postgresql /prometheus job 不动):
- job_name: 'mysql'
scrape_interval: 5s
static_configs:
- targets: ['192.168.56.132:9104']
labels:
instance: 'prod-mysql-01'
env: 'production'
备份:cp prometheus.yml prometheus.yml.bak
6.2 重载 Prometheus
systemctl reload prometheus # 或 systemctl restart prometheus
6.3 验证抓取目标与指标入库
curl -s http://127.0.0.1:9090/api/v1/targets | python3 -m json.tool
# mysql job → health: up, lastError: ""
curl -s 'http://127.0.0.1:9090/api/v1/query?query=mysql_up'
# mysql_up = 1
✅ 结果:Prometheus 已抓取 MySQL 指标并写入 TSDB。
7. 配置 Grafana 展示(详细步骤)
7.1 确认数据源
curl -s -u admin:Lihj2026 http://127.0.0.1:3000/api/datasources
# 已有 Prometheus 数据源,url= http://192.168.56.132:9090/ , isDefault=true
Grafana admin 密码经试探为
Lihj2026(默认配置里写的 admin 已被改)。
7.2 创建 MySQL 监控 Dashboard(API 方式)
用 Grafana API 提交 Dashboard JSON(含核心面板):
curl -s -u admin:Lihj2026 -X POST http://127.0.0.1:3000/api/dashboards/db \
-H "Content-Type: application/json" -d '{
"dashboard": {
"title": "MySQL Monitoring",
"refresh": "10s",
"panels": [
{"id":1,"title":"MySQL Up","type":"stat","targets":[{"expr":"mysql_up"}]},
{"id":2,"title":"Uptime (hours)","type":"stat","targets":[{"expr":"mysql_global_status_uptime/3600"}]},
{"id":3,"title":"Connections","type":"graph","targets":[{"expr":"sum(rate(mysql_global_status_threads_connected[1m]))"}]},
{"id":4,"title":"QPS (Queries/sec)","type":"graph","targets":[{"expr":"sum(rate(mysql_global_status_questions[1m]))"}]},
{"id":5,"title":"Threads Running","type":"graph","targets":[{"expr":"mysql_global_status_threads_running"}]},
{"id":6,"title":"Innodb Buffer Pool Hit Ratio","type":"graph","targets":[{"expr":"100 - (sum(rate(mysql_global_status_innodb_buffer_pool_reads[1m]))*100 / sum(rate(mysql_global_status_innodb_buffer_pool_read_requests[1m])))"}]}
]
},
"overwrite": true
}'
✅ 结果:Dashboard 创建成功,URL /d/H2Xa-frDk/mysql-monitoring。
7.3 端到端验证
curl -s -u admin:Lihj2026 \
'http://127.0.0.1:3000/api/datasources/proxy/1/api/v1/query?query=mysql_up'
# {"status":"success","data":{"result":[... "value":[...,"1"]]}}
8. 服务管理与维护
8.1 服务状态命令
systemctl status mysqld mysqld-exporter prometheus
systemctl start|stop|restart mysqld mysqld-exporter
journalctl -u mysqld-exporter -n 50 # exporter 日志
8.2 健康检查
# MySQL 是否可达
mysql -uexporter -pexporter_pass -h127.0.0.1 -e "SELECT 1;"
# exporter 是否正常
curl -s http://127.0.0.1:9104/metrics | grep '^mysql_up'
# Prometheus 采集目标
curl -s 'http://127.0.0.1:9090/api/v1/targets' | python3 -m json.tool
# Grafana 面板
http://192.168.56.132:3000/d/H2Xa-frDk/mysql-monitoring
8.3 常见故障排查
| 现象 | 排查方向 |
|---|---|
mysql_up=0 |
exporter 连不上库;检查 /root/.my.cnf、账号权限、3306 端口 |
| exporter 报连接拒绝 | 确认 MySQL 运行、bind-address=0.0.0.0、监控账号存在 |
| 下载失败 SSL errno 104 | GitHub 直连不通,换 ghfast.top/gh-proxy.com 代理 |
| Prometheus target down | 确认 9104 监听、prometheus.yml 语法、已 reload |
| Grafana 无数据 | 确认数据源 URL 正确、Prometheus 在抓取、指标存在 |
Grafana 面板 502 proxy error: context canceled |
多为面板初次打开/数据刚入库初期,query_range 落在数据稀疏期+高频刷新所致;Prometheus 本身无错误即非持续故障。自检:systemctl is-active prometheus、curl http://127.0.0.1:9090/api/v1/targets、curl -u admin:Lihj2026 'http://127.0.0.1:3000/api/datasources/proxy/1/api/v1/query?query=mysql_up' |
8.4 TSDB 维护(同 Prometheus 通用)
-
数据目录
/var/lib/prometheus,默认保留 15 天。 -
查看占用:
du -sh /var/lib/prometheus。 -
调整保留期:
prometheus.service加--storage.tsdb.retention.time=30d。
9. 已知问题与待办
-
mysqld 与 mysqld-exporter 未设置开机自启(
disabled),重启后需手动启动。建议systemctl enable mysqld mysqld-exporter。 -
Grafana 手动启动(非 systemd 托管),重启系统后丢失,建议迁移为 systemd 服务。
-
root 密码已在本次重置为
Lihj2026(原密码未知),需妥善记录。 -
多实例配置
/etc/my.cnf(3306/3307 主从)仍保留未启用,其二进制/usr/local/mysql/bin/mysqld缺失,属废弃残留;如需启用需先补齐二进制。 -
面板为自定义精简版已完成:2026-10-10 新增完整面板MySQL Overview (Full),见第 12 章。
10. 关键文件清单
| 文件 | 用途 |
|---|---|
/etc/my_mysql.cnf |
MySQL 独立配置(不碰 /etc/my.cnf) |
/etc/systemd/system/mysqld.service.d/override.conf |
让 mysqld 用独立配置启动 |
/etc/systemd/system/mysqld-exporter.service |
exporter systemd 服务 |
/root/.my.cnf |
exporter 连库凭据(600) |
/usr/local/bin/mysqld_exporter |
exporter 二进制 |
/etc/prometheus/prometheus.yml |
采集配置(含 mysql job,备份 .bak) |
11. 快速访问入口
| 资源 | 地址 |
|---|---|
| Grafana 登录 | http://192.168.56.132:3000 (admin / Lihj2026) |
| MySQL 监控面板 | http://192.168.56.132:3000/d/H2Xa-frDk/mysql-monitoring |
| MySQL 完整面板 | http://192.168.56.132:3000/d/cninLfrvk/mysql-overview-full |
| Prometheus UI | http://192.168.56.132:9090 |
| exporter 指标 | http://192.168.56.132:9104/metrics |
12. 完整 MySQL 监控面板:MySQL Overview (Full)
12.1 为什么之前"指标少"
mysqld_exporter 实际已采集 723 个 mysql_* 指标(/metrics 共 764 个指标),Prometheus 全部入库、Grafana 均可查。之前看着少,是因为自定义面板 MySQL Monitoring 只画了 6 个图——不是没数据,是面板精简。
12.2 官方面板(Grafana.com id 7362)为何不直接导入
- 服务器与本机访问
grafana.com均超时(HTTP 000),无法直接下载面板 JSON。 - 且 7362 是 2018 年 Percona PMM 时代的旧模板,依赖 node_exporter 的
node_*指标和$host变量,直接导入会大量空图。
12.3 已交付:基于真实指标的完整 Overview
用当前环境实际存在的指标通过 Grafana API 生成,覆盖 24 个 panel(6 个分栏 Row),全部查询已逐一验证可取数(OK):
| 分栏 Row | 面板 |
|---|---|
| Overview | MySQL Up / Uptime(days) / Running Threads / Threads Connected / Max Used Connections / Aborted Clients |
| Connections | Connections /sec / Threads Connected&Running / Max Used Connections |
| Queries | Questions(QPS) / Queries Total / Commands Breakdown / Key Command QPS / Temp Tables |
| InnoDB | Buffer Pool Hit Ratio / Reads&Writes / Buffer Pool Pages / Row Lock Waits / Log Writes |
| Network & Cache | Bytes Sent&Received / Key Cache Hit Ratio |
关键点:命令 QPS 用
mysql_global_status_commands_total{command="Com_select/insert/update/delete"}(v0.17.2 已把命令类指标统一到这里),不再用旧版mysql_global_status_com_select(不存在,会OK(0))。
访问:http://192.168.56.132:3000/d/cninLfrvk/mysql-overview-full(uid cninLfrvk,已设置 instance 模板变量自动匹配)。
本文档基于 2026-10-10 对 node2 (192.168.56.132) 的完整搭建过程整理,命令均经实际执行验证。
浙公网安备 33010602011771号