目录
Prometheus 监控 MySQL
一、架构说明
核心逻辑:MySQL 实例注册到 Consul(服务注册)→ Prometheus 配置 Consul 服务发现(自动发现 MySQL 实例)→ MySQL 暴露监控指标(via mysqld_exporter)→ Prometheus 拉取指标 → 可视化/告警。
组件角色:
- Consul:服务注册中心,存储 MySQL 服务的地址、端口、元数据(如用户名、密码)。
- mysqld_exporter:MySQL 监控指标采集器,部署在 MySQL 节点(或独立部署),连接 MySQL 并暴露
/metrics接口。 - Prometheus:通过 Consul 发现所有 MySQL 实例,定期拉取
mysqld_exporter的指标。 - MySQL:被监控目标,需开启远程访问权限(供 exporter 连接)。
二、前置条件
- 已部署 Consul 集群(单节点可用于测试),确保 Prometheus 能访问 Consul 的 HTTP 接口(默认 8500 端口)。
- 已部署 Prometheus(2.x+ 版本),配置文件可编辑。
- MySQL 实例(5.7+ 或 8.0+),支持远程连接(防火墙开放 3306 端口)。
- 所有组件网络互通:Prometheus ↔ Consul、Prometheus ↔ mysqld_exporter、mysqld_exporter ↔ MySQL。
三、步骤 1:部署 mysqld_exporter(MySQL 指标采集)
mysqld_exporter 是 Prometheus 官方提供的 MySQL 监控采集器,需在每个 MySQL 节点(或独立节点)部署。
3.1 下载并安装 mysqld_exporter
# 下载最新版本(可替换为官网最新版本)
wget https://github.com/prometheus/mysqld_exporter/releases/download/v0.18.0/mysqld_exporter-0.18.0.linux-amd64.tar.gz
# 解压并移动到指定目录
tar xvf mysqld_exporter-0.18.0.linux-amd64.tar.gz -C /data/monitor/
cd /data/monitor/
mv mysqld_exporter-0.18.0.linux-amd64 mysqld_exporter
# 验证安装
mysqld_exporter --version # 输出版本信息则成功
3.2 配置 MySQL 授权(供 exporter 连接)
exporter 需要连接 MySQL 采集指标,需创建专用监控用户并授权:
-- 登录 MySQL(本地或远程)
mysql -u root -p
-- 创建监控用户(允许 exporter 所在节点访问,% 表示所有地址,生产建议限制 IP)
CREATE USER 'prometheus'@'127.0.0.1' IDENTIFIED BY 'YourStrongPassword123!';
-- 授予监控所需权限(最小权限原则)
GRANT PROCESS, REPLICATION CLIENT, SELECT ON *.* TO 'prometheus'@'127.0.0.1';
-- 刷新权限
FLUSH PRIVILEGES;
3.3 配置 mysqld_exporter 连接 MySQL
创建 exporter 的配置文件,存储 MySQL 连接信息:
# 创建配置文件目录
mkdir -p /data/monitor/mysqld_exporter/
# 编写配置文件(指定 MySQL 连接信息)
cat > /data/monitor/mysqld_exporter/.my.cnf << EOF
[client]
user=prometheus
password=YourStrongPassword123!
host=127.0.0.1
port=3306
EOF
# 授权(避免权限问题)
chmod 600 /data/monitor/mysqld_exporter/.my.cnf
chown root:root /data/monitor/mysqld_exporter/.my.cnf
3.4 系统服务方式启动 exporter
# 创建系统服务文件
cat > /etc/systemd/system/mysqld-exporter.service << EOF
[Unit]
Description=Prometheus MySQL Exporter
After=network.target
[Service]
User=root
Group=root
ExecStart=/data/monitor/mysqld_exporter/mysqld_exporter --config.my-cnf=/data/monitor/mysqld_exporter/.my.cnf --web.listen-address=:9104
Restart=always
[Install]
WantedBy=multi-user.target
EOF
# 重载服务配置、启动并设置开机自启
systemctl daemon-reload
systemctl start mysqld-exporter
systemctl enable mysqld-exporter
# 验证启动状态(默认暴露 9104 端口)
systemctl status mysqld-exporter
curl http://[IP]:9104/metrics # 能看到指标则成功

四、步骤 2:MySQL 服务注册到 Consul
Consul 支持服务注册(手动注册/自动注册),这里提供两种方式(推荐手动注册用于测试,生产可结合 Consul Agent 自动注册)。
方式 1:手动注册(通过 Consul HTTP API)
适合临时测试或少量实例,无需在 MySQL 节点部署 Consul Agent:
# 向 Consul 注册 MySQL 服务(替换以下参数)
# Consul 地址:192.168.37.40:8500(Consul Server 或 Client 的 HTTP 端口)
# 服务名称:mysqld-exporter(Prometheus 后续通过该名称发现)
# 服务地址:192.168.37.21(MySQL 节点 IP,即 mysqld_exporter 所在 IP)
# 服务端口:9104(mysqld_exporter 暴露的端口)
# 元数据(可选):可存储 MySQL 实例名称、环境等,供 Prometheus 筛选
curl http://192.168.37.40:8500/v1/agent/service/register -X PUT -i -H "Content-Type:application/json" -H "X-Consul-Token: f5cc7d96-ba0f-0501-4252-903e059514bb" -d '{
"ID": "mysql-192.168.37.21:3306",
"Name": "mysqld-exporter",
"Tags": [
"mysqld-exporter",
"dev"
],
"Address": "192.168.37.21",
"Port": 9104,
"EnableTagOverride": false,
"Check": {
"DeregisterCriticalServiceAfter": "90m",
"HTTP": "http://192.168.37.21:9104/metrics",
"Interval": "10s",
"timeout": "2s"
}
}'
方式 2:自动注册(通过 Consul Agent)
适合生产环境(多实例、动态扩容),需在每个 MySQL 节点部署 Consul Agent(作为 Client 加入 Consul 集群):
- 部署 Consul Agent(参考 Consul 官方文档),确保 Agent 已加入集群。
- 创建服务注册配置文件:
# 在 MySQL 节点(Consul Agent 所在节点)创建服务配置
mkdir -p /etc/consul.d
cat > /etc/consul.d/mysql-monitor.json << EOF
{
"service": {
"id": "mysql-$(hostname -i):9104", # 自动获取 IP 作为唯一 ID
"name": "mysql-monitor", # 服务名称(与手动注册一致)
"port": 9104,
"tags": ["env=prod", "instance=mysql-slave"],
"meta": {
"mysql_host": "$(hostname -i)",
"mysql_port": 3306
},
"checks": [ # 健康检查(可选,Consul 定期检测 exporter 是否存活)
{
"http": "http://$(hostname -i):9104/metrics",
"interval": "10s",
"timeout": "3s"
}
]
}
}
EOF
- 重启 Consul Agent 加载配置:
systemctl restart consul
验证服务注册结果
访问 Consul UI(默认 http://Consul-IP:8500/ui),在「Services」中查看 mysql-monitor 服务,状态为「Healthy」则注册成功。

五、步骤 3:Prometheus 配置 Consul 服务发现
修改 Prometheus 配置文件,添加 Consul 服务发现规则,让 Prometheus 自动发现所有注册到 Consul 的 mysql-monitor 服务。
5.1 编辑 Prometheus 配置文件(prometheus.yml)
global:
scrape_interval: 15s # 全局拉取间隔
scrape_configs:
# 其他已有配置(如 node_exporter)...
# 添加 MySQL 监控的 Consul 服务发现配置
- job_name: 'mysqld-exporter' # 任务名称(自定义)
consul_sd_configs:
- server: '192.168.37.40:8500' # Consul 的 HTTP 地址(Server 或 Client)
datacenter: 'dc1' # 与 Consul 注册时的 datacenter 一致
tag_separator: ','
scheme: 'http'
services: ['mysqld-exporter'] # 只发现 Consul 中名称为 mysql-monitor 的服务
# 可选:过滤标签(只发现 tags 包含 env=prod 的服务)
# filter: 'ServiceTags contains "env=prod"'
# 可选:重写拉取路径(默认 /metrics,exporter 无需修改则无需配置)
metrics_path: '/metrics'
# 可选:添加标签(用于区分环境、实例)
relabel_configs:
# 从 Consul 服务的 meta 中提取 mysql_host 作为标签
- source_labels: [__meta_consul_service_meta_mysql_host]
target_label: mysql_host
# 从 Consul 服务的 tags 中提取 env 作为标签
- source_labels: [__meta_consul_service_tag_env]
target_label: env
# 从 Consul 服务的 ID 中提取实例信息
- source_labels: [__meta_consul_service_id]
target_label: instance
5.2 验证 Prometheus 配置并重启
# 验证配置文件语法是否正确
promtool check config /etc/prometheus/prometheus.yml
# 重启 Prometheus 加载配置
systemctl restart prometheus
5.3 确认服务发现结果
访问 Prometheus UI(默认 http://Prometheus-IP:9090):
- 进入「Status → Targets」,查看
mysql-monitor任务。 - 若所有 MySQL 实例的 State 为「UP」,说明服务发现成功,Prometheus 已开始拉取指标。

六、步骤 4:可视化监控(Grafana)
Prometheus 本身不擅长可视化,推荐使用 Grafana 导入 MySQL 监控面板。
4.1 导入 MySQL 监控面板
- 登录 Grafana(已集成 Prometheus 数据源)。
- 进入「Dashboards → Import」,输入 MySQL 官方面板 ID:7362(或搜索「MySQL by Prometheus & mysqld_exporter」)。
- 选择 Prometheus 数据源,点击「Import」,即可看到完整的 MySQL 监控面板(包含连接数、QPS、慢查询、表空间、索引命中率等指标)。
七、Mysql监控指标
MySQL 核心监控指标清单(按维度分类)
一、可用性指标(基础必监控)
| 指标名 | 指标含义 | 核心 PromQL 查询 | 监控意义 |
|---|---|---|---|
mysql_up | MySQL 实例是否在线 | mysql_up | 直接判断实例是否存活(1=在线,0=离线) |
mysql_global_status_uptime | 实例运行时长(秒) | mysql_global_status_uptime | 检测实例是否频繁重启(数值骤降) |
二、连接数指标(避免连接耗尽)
| 指标名 | 指标含义 | 核心 PromQL 查询 | 监控意义 |
|---|---|---|---|
mysql_global_status_connections | 当前已建立的连接数 | mysql_global_status_connections | 实时查看连接数变化 |
mysql_global_variables_max_connections | 最大允许连接数 | mysql_global_variables_max_connections | 配置基准值 |
| - | 连接数使用率 | mysql_global_status_connections / mysql_global_variables_max_connections | 核心:超过80%需告警 |
mysql_global_status_aborted_connects | 失败的连接尝试数 | increase(mysql_global_status_aborted_connects[5m]) | 检测密码错误、权限问题等连接失败 |
三、性能指标(定位慢查询/锁/临时表问题)
| 指标名 | 指标含义 | 核心 PromQL 查询 | 监控意义 |
|---|---|---|---|
mysql_global_status_slow_queries | 慢查询总数 | increase(mysql_global_status_slow_queries[5m]) | 慢查询突增→SQL 性能问题 |
mysql_global_status_table_locks_waited | 表锁等待次数 | increase(mysql_global_status_table_locks_waited[5m]) | 锁等待频繁→长事务/慢 SQL |
mysql_global_status_created_tmp_tables | 临时表创建总数 | increase(mysql_global_status_created_tmp_tables[5m]) | 临时表过多→SQL 未优化 |
mysql_global_status_created_tmp_disk_tables | 磁盘临时表创建数 | increase(mysql_global_status_created_tmp_disk_tables[5m]) / increase(mysql_global_status_created_tmp_tables[5m]) | 占比超20%→需调优 tmp_table_size |
mysql_global_status_handler_read_rnd | 随机读次数 | rate(mysql_global_status_handler_read_rnd[1m]) | 数值过高→缺少索引 |
四、流量指标(QPS/TPS/网络吞吐)
| 指标名 | 指标含义 | 核心 PromQL 查询 | 监控意义 |
|---|---|---|---|
mysql_global_status_queries | 总查询数 | rate(mysql_global_status_queries[1m]) | 计算 QPS(每秒查询数)→流量波动 |
mysql_global_status_handler_commit | 事务提交数 | rate(mysql_global_status_handler_commit[1m]) - rate(mysql_global_status_handler_rollback[1m]) | 计算 TPS(每秒事务数)→写入负载 |
mysql_global_status_bytes_received | 网络流入字节总数 | rate(mysql_global_status_bytes_received[1m]) | 流入流量→数据写入/攻击检测 |
mysql_global_status_bytes_sent | 网络流出字节总数 | rate(mysql_global_status_bytes_sent[1m]) | 流出流量→数据查询/泄露检测 |
五、存储指标(磁盘/空间)
| 指标名 | 指标含义 | 核心 PromQL 查询 | 监控意义 |
|---|---|---|---|
mysql_disk_used_bytes | 数据目录已用磁盘空间 | mysql_disk_used_bytes | 实时查看磁盘使用量 |
mysql_disk_total_bytes | 数据目录总磁盘空间 | mysql_disk_used_bytes / mysql_disk_total_bytes | 使用率超85%→需扩容/清理 |
mysql_global_status_disk_full | 磁盘满错误数 | increase(mysql_global_status_disk_full[5m]) | 检测磁盘满导致的写失败 |
六、主从复制指标(同步状态)
| 指标名 | 指标含义 | 核心 PromQL 查询 | 监控意义 |
|---|---|---|---|
mysql_slave_seconds_behind_master | 从库延迟秒数 | mysql_slave_seconds_behind_master | 延迟超60秒→同步异常 |
mysql_slave_io_running | IO 线程是否运行 | mysql_slave_io_running (1=运行,0=停止) | IO 线程停止→同步中断 |
mysql_slave_sql_running | SQL 线程是否运行 | mysql_slave_sql_running (1=运行,0=停止) | SQL 线程停止→数据同步失败 |
八、告警
告警规则
groups:
- name: mysql_alerts
rules:
# ========== 基础可用性告警 ==========
# 1. MySQL 服务不可用
- alert: MySQLDown
expr: mysql_up == 0
for: 30s
labels:
severity: critical
service: mysql
annotations:
summary: "MySQL 服务不可用 ({{ $labels.instance }})"
description: "MySQL 实例 {{ $labels.instance }} 已下线超过 30 秒,请检查服务状态。"
# 2. MySQL 连接数过高
- alert: MySQLTooManyConnections
expr: mysql_global_status_connections / mysql_global_variables_max_connections > 0.8
for: 2m
labels:
severity: warning
service: mysql
annotations:
summary: "MySQL 连接数过高 ({{ $labels.instance }})"
description: "MySQL 实例 {{ $labels.instance }} 连接数使用率超过 80% (当前: {{ $value | humanizePercentage }}),请检查是否有连接泄露或业务突增。"
# 3. MySQL 慢查询数突增
- alert: MySQLSlowQueriesIncreasing
expr: increase(mysql_global_status_slow_queries[5m]) > 10
for: 5m
labels:
severity: warning
service: mysql
annotations:
summary: "MySQL 慢查询数突增 ({{ $labels.instance }})"
description: "MySQL 实例 {{ $labels.instance }} 最近 5 分钟慢查询数增加了 {{ $value }} 个,需检查慢查询日志优化 SQL。"
# 4. MySQL 磁盘使用率过高(数据目录)
- alert: MySQLDiskUsageHigh
expr: mysql_disk_used_bytes / mysql_disk_total_bytes > 0.85
for: 5m
labels:
severity: warning
service: mysql
annotations:
summary: "MySQL 磁盘使用率过高 ({{ $labels.instance }})"
description: "MySQL 实例 {{ $labels.instance }} 数据目录磁盘使用率超过 85% (当前: {{ $value | humanizePercentage }}),请清理数据或扩容磁盘。"
# 5. MySQL 主从复制延迟
- alert: MySQLReplicationLag
expr: mysql_slave_seconds_behind_master > 60
for: 2m
labels:
severity: critical
service: mysql
annotations:
summary: "MySQL 主从复制延迟 ({{ $labels.instance }})"
description: "MySQL 从库 {{ $labels.instance }} 复制延迟超过 60 秒 (当前: {{ $value }} 秒),请检查主从同步状态。"
# 6. MySQL 表锁等待时间过长
- alert: MySQLTableLockWaits
expr: mysql_global_status_table_locks_waited > 0 and increase(mysql_global_status_table_locks_waited[5m]) > 10
for: 1m
labels:
severity: warning
service: mysql
annotations:
summary: "MySQL 表锁等待频繁 ({{ $labels.instance }})"
description: "MySQL 实例 {{ $labels.instance }} 最近 5 分钟表锁等待数增加 {{ $value }} 次,可能存在长事务或慢 SQL。"
# 7. MySQL 临时表创建过多(磁盘临时表)
- alert: MySQLTempTablesOnDisk
expr: increase(mysql_global_status_created_tmp_disk_tables[5m]) / increase(mysql_global_status_created_tmp_tables[5m]) > 0.2
for: 5m
labels:
severity: warning
service: mysql
annotations:
summary: "MySQL 磁盘临时表占比过高 ({{ $labels.instance }})"
description: "MySQL 实例 {{ $labels.instance }} 磁盘临时表占比超过 20% (当前: {{ $value | humanizePercentage }}),需优化 SQL 或调整 tmp_table_size 配置。"
# ========== 流量相关告警(修正核心指标名) ==========
# 8. MySQL 每秒查询量(QPS)突增
- alert: MySQLQPSHigh
expr: rate(mysql_global_status_queries[1m]) > 5000 # 标准指标名:mysql_global_status_queries
for: 2m
labels:
severity: warning
service: mysql
annotations:
summary: "MySQL QPS 突增 ({{ $labels.instance }})"
description: "MySQL 实例 {{ $labels.instance }} 每秒查询量超过 5000 (当前: {{ $value | humanize }}),可能存在流量洪峰或异常查询。"
# 9. MySQL 每秒查询量(QPS)突降
- alert: MySQLQPSLow
expr: rate(mysql_global_status_queries[1m]) < 100 # 标准指标名:mysql_global_status_queries
for: 5m
labels:
severity: warning
service: mysql
annotations:
summary: "MySQL QPS 突降 ({{ $labels.instance }})"
description: "MySQL 实例 {{ $labels.instance }} 每秒查询量低于 100 (当前: {{ $value | humanize }}),可能存在业务中断或采集异常。"
# 10. MySQL 网络流入流量过高
- alert: MySQLNetworkInHigh
expr: rate(mysql_global_status_bytes_received[1m]) > 10485760 # 10MB/s,标准指标名
for: 3m
labels:
severity: warning
service: mysql
annotations:
summary: "MySQL 流入流量过高 ({{ $labels.instance }})"
description: "MySQL 实例 {{ $labels.instance }} 每秒流入流量超过 10MB (当前: {{ $value | humanizeBytes }}/s),可能存在大量数据写入或网络攻击。"
# 11. MySQL 网络流出流量过高
- alert: MySQLNetworkOutHigh
expr: rate(mysql_global_status_bytes_sent[1m]) > 10485760 # 10MB/s,标准指标名
for: 3m
labels:
severity: warning
service: mysql
annotations:
summary: "MySQL 流出流量过高 ({{ $labels.instance }})"
description: "MySQL 实例 {{ $labels.instance }} 每秒流出流量超过 10MB (当前: {{ $value | humanizeBytes }}/s),可能存在大量数据查询或数据泄露风险。"
# 12. MySQL 每秒写入量(TPS)突增
- alert: MySQLTPSHigh
expr: rate(mysql_global_status_handler_commit[1m]) - rate(mysql_global_status_handler_rollback[1m]) > 1000 # 标准指标名
for: 2m
labels:
severity: warning
service: mysql
annotations:
summary: "MySQL TPS 突增 ({{ $labels.instance }})"
description: "MySQL 实例 {{ $labels.instance }} 每秒事务数超过 1000 (当前: {{ $value | humanize }}),可能存在批量写入或业务峰值。"
压测和告警
关于Mysql压测,之前写过一个文章
MySQL 压测实战:sysbench 从入门到精通
关于告警配置(钉钉)
告警通知实现 - 邮件 + 钉钉 + 自定义告警模板
3504

被折叠的 条评论
为什么被折叠?



