菲哥!主库连不上了!运营说用户付了钱下不了单!我正喝奶茶,运维的消息像炸弹一样炸过来。登上去一看,主库 CPU 100% 跑了快半小时,慢查询堆了 200 多条,而运维一脸懵:“我也不知道啊,没人告诉我有问题啊!”
这事儿太常见了:很多人用 MySQL 就像 “开盲盒”—— 平时不管不问,出问题才慌手慌脚。其实 MySQL 监控就像 “给数据库装个体温计 + 报警器”,CPU 高了、连接数满了、慢查询多了,能提前预警,不用等业务崩了才救火。
一、先扎心:为什么你总在 “业务崩了才知道 MySQL 有问题”?
很多人对监控的理解是 “装个工具就行”,结果要么监控了没用的指标(比如 “MySQL 版本号”),要么告警太敏感(半夜三点因为 “QPS 涨了 10%” 被吵醒),要么干脆没告警 —— 这不是监控,是 “装样子”。
先上一张 “无效监控 vs 有效监控” 的灵魂对比图,看看你中招没:
plaintext
【无效监控流程】
装了监控工具 → 只看“MySQL是否存活” → 告警阈值乱设(CPU>50%就告警) → 半夜被无关告警吵醒 → 后来干脆关了告警 → 主库崩了才发现(业务停1小时)
【有效监控流程】
选关键指标(QPS/CPU/慢查询) → 设合理阈值(CPU>85%持续5分钟告警) → 告警发企业微信+邮件 → 提前1小时收到“CPU飙升”预警 → 5分钟解决(业务没影响) → 继续摸鱼喝奶茶
举个真实例子:之前帮某电商搭监控,刚搭好第二天就告警 “慢查询数突增到 100 条 / 分钟”,查发现是开发上线了一条没加索引的 SQL,及时回滚,没影响用户 —— 这就是监控的价值:把 “事后救火” 变成 “事前预防”。
二、监控什么?MySQL 核心指标 “避雷清单”(表格 + 幽默解读)
监控不是 “越多越好”,就像你不会每天盯着家里所有电器的功率看,只需要看 “电表是否异常、燃气是否漏气”。MySQL 监控也一样,抓准 6 个核心指标,90% 的问题都能提前发现。
我把这些指标做成了 “监控避雷表”,每个指标都标了 “异常值” 和 “解决办法”,下次看监控直接对照:
| 监控指标 | 含义(幽默解读) | 正常范围 | 异常值判断(要告警) | 实战解决办法(别慌) |
|---|---|---|---|---|
| QPS | 每秒执行的 SQL 数(像超市收银台的顾客流量) | 视业务而定(比如订单库 500-2000) | 突然涨 3 倍(如从 1000→3000)或跌为 0 | 涨:查是否有异常查询(如爬虫);跌:查应用是否连不上库 |
| 慢查询数 / 分钟 | 每分钟超过 1 秒的 SQL 数(慢得让用户骂街的 SQL) | 0-5 条 / 分钟 | 突然≥10 条 / 分钟,或持续增长 | 查慢查询日志,看是不是新 SQL 没加索引 |
| CPU 使用率 | MySQL 占的 CPU 百分比(数据库的 “体力消耗”) | 日常≤60%,峰值≤80% | 持续 5 分钟≥85% | 查是否有全表扫 SQL,或调整参数(如 innodb_buffer_pool_size) |
| 连接数(Threads_connected) | 当前连接到 MySQL 的数量(数据库的 “接待人数”) | ≤max_connections 的 70%(如 max=1000,≤700) | 持续 5 分钟≥90% max_connections | 查是否有连接泄漏(应用没关连接),或调大 max_connections(谨慎) |
| InnoDB Buffer Pool 命中率 | 内存缓存命中率(数据库 “记东西的能力”) | ≥99% | 持续 5 分钟≤98% | 调大 innodb_buffer_pool_size(如从 2G→4G) |
| 磁盘空间使用率 | 数据目录占的磁盘百分比(数据库的 “仓库满没满”) | ≤70% | ≥85% | 删无用日志(如 binlog),或扩容磁盘 |
避坑提醒:别监控这些 “没用的指标”!
比如 “MySQL 版本号”“当前用户数”—— 这些指标不会变,监控了也没用;比如 “innodb_log_write_requests”(日志写入请求数)—— 太底层,非专家看不懂,不如看 “慢查询数” 直接。
三、用 Prometheus+Grafana 搭监控
现在主流的 MySQL 监控组合是 “Prometheus(存数据)+ MySQL Exporter(取数据)+ Grafana(画仪表盘)”,就像 “水库(Prometheus)+ 抽水机(Exporter)+ 显示屏(Grafana)”,一步步搭起来很简单。
1. 先看架构图(数据怎么流,一眼看懂)
plaintext
【MySQL监控架构图】
MySQL数据库 → MySQL Exporter(采集MySQL指标,比如QPS、CPU) → Prometheus(存储指标数据,按时间存) → Grafana(读取Prometheus数据,画成仪表盘,比如CPU折线图) → AlertManager(从Prometheus拿告警规则,发企业微信)
2. 步骤 1:安装 MySQL Exporter(“抽水机”,采集 MySQL 指标)
Exporter 是连接 MySQL 和 Prometheus 的桥梁,负责从 MySQL 里拿指标数据。
(1)下载并解压 Exporter(Linux 为例)
bash
# 下载Exporter(选最新版,这里用0.15.1)
wget https://github.com/prometheus/mysqld_exporter/releases/download/v0.15.1/mysqld_exporter-0.15.1.linux-amd64.tar.gz
# 解压
tar -zxvf mysqld_exporter-0.15.1.linux-amd64.tar.gz
mv mysqld_exporter-0.15.1.linux-amd64 /usr/local/mysqld_exporter
(2)给 Exporter 创建 MySQL 账号(让 Exporter 能读 MySQL 指标)
登录 MySQL,创建一个只读账号(只给必要权限,别给 root):
sql
-- 创建账号exporter,允许本地连接(Exporter和MySQL在同一台机器)
CREATE USER 'exporter'@'localhost' IDENTIFIED WITH mysql_native_password BY 'Exporter@123';
-- 授予读取指标的权限(别多给,安全第一)
GRANT PROCESS, REPLICATION CLIENT, SELECT ON *.* TO 'exporter'@'localhost';
-- 刷新权限
FLUSH PRIVILEGES;
(3)配置 Exporter 连接 MySQL
创建一个配置文件,写 MySQL 账号密码:
bash
# 新建配置文件
vi /usr/local/mysqld_exporter/.my.cnf
# 写入以下内容(MySQL账号密码)
[client]
user=exporter
password=Exporter@123
host=localhost
port=3306
(4)启动 Exporter(后台运行)
bash
# 启动Exporter,指定配置文件,端口用9104(默认)
nohup /usr/local/mysqld_exporter/mysqld_exporter --config.my-cnf=/usr/local/mysqld_exporter/.my.cnf --web.listen-address=:9104 &
# 验证是否启动成功(访问9104端口,能看到指标就对了)
curl http://localhost:9104/metrics
看到一堆以 “mysql_” 开头的指标(如),说明 Exporter 没问题。
mysql_global_status_queries_total
3. 步骤 2:安装 Prometheus(“水库”,存指标数据)
Prometheus 负责定时从 Exporter 拿数据,按时间序列存起来,方便后续查询。
(1)下载并解压 Prometheus
bash
# 下载Prometheus(选最新版,这里用2.45.0)
wget https://github.com/prometheus/prometheus/releases/download/v2.45.0/prometheus-2.45.0.linux-amd64.tar.gz
# 解压
tar -zxvf prometheus-2.45.0.linux-amd64.tar.gz
mv prometheus-2.45.0.linux-amd64 /usr/local/prometheus
(2)配置 Prometheus,让它拉取 Exporter 的指标
修改 Prometheus 的配置文件:
prometheus.yml
bash
vi /usr/local/prometheus/prometheus.yml
在里加一段 MySQL 的配置(告诉 Prometheus 去哪里拿数据):
scrape_configs
yaml
scrape_configs:
- job_name: "prometheus"
static_configs:
- targets: ["localhost:9090"] # Prometheus自己的指标
# 新增MySQL的监控任务
- job_name: "mysql"
static_configs:
- targets: ["localhost:9104"] # Exporter的地址和端口
scrape_interval: 15s # 每15秒拉取一次数据(别太频繁,占资源)
(3)启动 Prometheus(后台运行)
bash
# 启动Prometheus,指定配置文件
nohup /usr/local/prometheus/prometheus --config.file=/usr/local/prometheus/prometheus.yml &
# 验证:访问Prometheus的web界面(端口9090)
# 浏览器打开http://你的服务器IP:9090,在Graph里输入mysql_up,能看到1(表示Exporter正常)
4. 步骤 3:安装 Grafana(“显示屏”,画可视化仪表盘)
Grafana 能把 Prometheus 里的枯燥数据,变成好看的折线图、饼图,比如 “CPU 使用率折线图”“慢查询数柱状图”,一眼看出问题。
(1)安装 Grafana(CentOS 为例)
bash
# 安装GPG密钥
wget -q -O - https://packages.grafana.com/gpg.key | sudo rpm --import -
# 添加Grafana仓库
echo "[$(date +%Y%m%d)] name=grafana" | sudo tee /etc/yum.repos.d/grafana.repo
echo "baseurl=https://packages.grafana.com/oss/rpm" | sudo tee -a /etc/yum.repos.d/grafana.repo
echo "enabled=1" | sudo tee -a /etc/yum.repos.d/grafana.repo
echo "gpgcheck=1" | sudo tee -a /etc/yum.repos.d/grafana.repo
echo "gpgkey=https://packages.grafana.com/gpg.key" | sudo tee -a /etc/yum.repos.d/grafana.repo
# 安装Grafana
sudo yum install -y grafana
# 启动Grafana并设为开机自启
sudo systemctl start grafana-server
sudo systemctl enable grafana-server
(2)配置 Grafana 连接 Prometheus
浏览器打开 Grafana(默认端口 3000):http:// 你的服务器 IP:3000,默认账号密码 admin/admin,第一次登录会让你改密码;点击左侧 “Configuration”→“Data Sources”→“Add data source”,选择 “Prometheus”;在 “URL” 里填 Prometheus 的地址:http://localhost:9090(如果不在同一台机器,填 Prometheus 的 IP:9090);点击 “Save & Test”,显示 “Data source is working” 就成功了。
(3)导入 MySQL 监控仪表盘(不用自己画,直接用现成的)
Grafana 有很多现成的 MySQL 仪表盘模板,不用自己一个个画指标,直接导入:
点击左侧 “+”→“Import”;在 “Import via grafana.com” 里输入模板 ID:7362(这是官方推荐的 MySQL 仪表盘,包含 QPS、CPU、连接数等所有核心指标);选择刚才添加的 Prometheus 数据源,点击 “Import”;搞定!现在你能看到一个完整的 MySQL 监控仪表盘,有折线图、柱状图,实时显示指标。
效果展示(幽默描述):
左边是 “CPU 使用率折线图”,如果突然往上飙,像 “爬山一样陡”,就知道要出事;中间是 “慢查询数柱状图”,如果柱子突然变高,像 “突然长高的树”,就赶紧查慢 SQL;下面是 “连接数仪表盘”,如果指针快指到红色区域,像 “汽车油表快到红线”,就查连接泄漏。
四、告警配置:让问题 “主动找你”(别等业务崩了)
监控搭好了,还得配告警 —— 不然你总不能 24 小时盯着仪表盘。我们用 Prometheus 的 AlertManager,把告警发到企业微信(或邮件),这样 “主库 CPU 高了”“慢查询多了”,你的企业微信会直接收到消息。
1. 步骤 1:配置 Prometheus 告警规则
先在 Prometheus 里定义 “什么情况算异常”,比如 “CPU>85% 持续 5 分钟”。
(1)创建告警规则文件
bash
# 新建告警规则目录和文件
mkdir -p /usr/local/prometheus/rules
vi /usr/local/prometheus/rules/mysql_alerts.yml
(2)写入常见的告警规则(直接套用)
yaml
groups:
- name: mysql_alerts
rules:
# 1. MySQL不可用告警(Exporter连不上MySQL)
- alert: MySQLDown
expr: mysql_up == 0
for: 1m
labels:
severity: critical # 紧急程度:严重
annotations:
summary: "MySQL数据库不可用"
description: "MySQL {{ $labels.instance }} 已经离线1分钟,请检查数据库是否正常运行!"
# 2. CPU使用率过高告警
- alert: MySQLHighCPU
expr: avg(rate(mysql_global_status_cpu_seconds_system[5m]) + rate(mysql_global_status_cpu_seconds_user[5m])) by (instance) > 0.85 # CPU>85%
for: 5m
labels:
severity: warning # 紧急程度:警告
annotations:
summary: "MySQL CPU使用率过高"
description: "MySQL {{ $labels.instance }} CPU使用率已经超过85%,持续5分钟,请检查是否有慢SQL!"
# 3. 慢查询数突增告警
- alert: MySQLHighSlowQueries
expr: rate(mysql_global_status_slow_queries[5m]) > 10 # 慢查询>10条/分钟
for: 3m
labels:
severity: warning
annotations:
summary: "MySQL慢查询数突增"
description: "MySQL {{ $labels.instance }} 慢查询数超过10条/分钟,持续3分钟,请查看慢查询日志!"
# 4. 连接数过高告警
- alert: MySQLHighConnections
expr: mysql_global_status_threads_connected / mysql_global_variables_max_connections > 0.9 # 连接数>90%max
for: 5m
labels:
severity: warning
annotations:
summary: "MySQL连接数过高"
description: "MySQL {{ $labels.instance }} 连接数已超过最大连接数的90%,持续5分钟,请检查是否有连接泄漏!"
(3)让 Prometheus 加载告警规则
修改 Prometheus 配置文件,添加规则文件路径:
prometheus.yml
yaml
rule_files:
- "rules/mysql_alerts.yml" # 刚才创建的告警规则文件
重启 Prometheus 让配置生效:
bash
# 找到Prometheus进程ID,杀死后重启
ps -ef | grep prometheus
kill -9 进程ID
nohup /usr/local/prometheus/prometheus --config.file=/usr/local/prometheus/prometheus.yml &
2. 步骤 2:配置 AlertManager,发告警到企业微信
AlertManager 负责把 Prometheus 的告警消息,发到企业微信(或邮件、短信)。
(1)下载并解压 AlertManager
bash
# 下载AlertManager(选最新版,这里用0.26.0)
wget https://github.com/prometheus/alertmanager/releases/download/v0.26.0/alertmanager-0.26.0.linux-amd64.tar.gz
# 解压
tar -zxvf alertmanager-0.26.0.linux-amd64.tar.gz
mv alertmanager-0.26.0.linux-amd64 /usr/local/alertmanager
(2)配置 AlertManager 对接企业微信
首先要在企业微信里创建 “应用”(拿到 CorpID、AgentID、Secret):
登录企业微信管理后台→“应用管理”→“创建应用”,填应用名称(如 “MySQL 告警”);记录下 “CorpID”(企业 ID)、“AgentID”(应用 ID);点击 “Secret”→“获取”,记录下 Secret(注意保密)。
然后修改 AlertManager 配置文件:
alertmanager.yml
bash
vi /usr/local/alertmanager/alertmanager.yml
写入以下配置(替换成你的企业微信信息):
yaml
global:
resolve_timeout: 5m # 告警解决后,5分钟内不重复发
route:
group_by: ['alertname'] # 按告警名称分组
group_wait: 10s # 同组告警等待10秒,一起发
group_interval: 10s # 同组告警间隔10秒发一次
repeat_interval: 1h # 同一告警1小时内不重复发
receiver: 'wechat' # 默认发给wechat接收器
receivers:
- name: 'wechat'
wechat_configs:
- corp_id: '你的企业微信CorpID'
to_party: '1' # 发给哪个部门(部门ID,1是根部门)
agent_id: '你的应用AgentID'
api_secret: '你的应用Secret'
send_resolved: true # 告警解决后,发“已解决”消息
(3)启动 AlertManager
bash
# 后台启动
nohup /usr/local/alertmanager/alertmanager --config.file=/usr/local/alertmanager/alertmanager.yml &
# 验证:访问AlertManager web界面(端口9093)
# 浏览器打开http://你的服务器IP:9093,能看到告警状态就对了
效果:
当 MySQL CPU>85% 持续 5 分钟,你的企业微信会收到一条消息:“【MySQL CPU 使用率过高】MySQL localhost:9104 CPU 使用率已经超过 85%,持续 5 分钟,请检查是否有慢 SQL!”—— 这样你不用盯仪表盘,问题会主动找你。
五、监控告警 “避坑指南”(实战踩过的坑,别再踩)
1. 坑 1:Exporter 连不上 MySQL,提示 “access denied”
原因:给 Exporter 的 MySQL 账号权限不够,或 IP 写错了(比如 Exporter 在另一台机器,却给了localhost权限)。解决:重新创建账号,允许 Exporter 的 IP 连接:
sql
DROP USER 'exporter'@'localhost';
CREATE USER 'exporter'@'192.168.1.200' IDENTIFIED WITH mysql_native_password BY 'Exporter@123'; # 192.168.1.200是Exporter的IP
GRANT PROCESS, REPLICATION CLIENT, SELECT ON *.* TO 'exporter'@'192.168.1.200';
FLUSH PRIVILEGES;
2. 坑 2:Grafana 仪表盘没数据,显示 “no data”
原因:Prometheus 没拉到 Exporter 的数据,或仪表盘模板 ID 选错了。解决:
先在 Prometheus 的 Graph 里输入,看是否有数据(值为 1);如果没数据,检查 Exporter 是否启动,Prometheus 配置里的 targets 是否正确;仪表盘模板 ID 用 7362(官方推荐),别用其他冷门模板。
mysql_up
3. 坑 3:告警太频繁,半夜被吵醒
原因:告警阈值设得太敏感(比如 CPU>60% 就告警),或时间太短(比如持续 1 分钟就告警)。解决:调整阈值和
for时间,比如 CPU>85% 持续 5 分钟,慢查询 > 10 条 / 分钟持续 3 分钟 —— 避免 “手抖一下” 就告警。
for
六、监控告警不是 “负担”,是 “摸鱼保障”
很多人觉得 “搭监控麻烦”,但搭好后你会发现:不用再担心 “主库突然崩了”,不用再半夜被电话吵醒,业务有问题会提前预警,5 分钟就能解决 —— 这才是 DBA 的 “躺平之道”。
记住:
监控核心指标,别贪多;告警阈值要合理,别太敏感;告警要发到手边(企业微信 / 手机),别只存在电脑上。















暂无评论内容