📌 今日关键词:性能监控、PMM、Prometheus、Grafana、慢查询、告警、指标体系
大家好,我是数据库小学妹 👋
前面我们学习了锁机制、MVCC、慢查询诊断这些"事后分析"的技术。但你知道
"数据库目前处于什么状态?QPS 多少?Buffer Pool 命中率是什么水平吗?"
听到QPS、命中率这些词是不是很懵?所以SQL写得好是一回事,知道数据库在"跑"什么状态是另一回事。
今天把我从零学监控的经历整理出来,新手也能从零搭建。
一、为什么需要监控?
先讲一个案例:
某平台电商大促,系统突然变慢。开发找运维,运维找 DBA,DBA 说"等我连上去看看"。这一套流程走了 15 分钟,用户已经跑到竞品下单了。
如果有一套监控,慢查询超过阈值就自动告警,早在用户察觉之前就能介入。
监控能帮你做什么?
| 目的 | 具体场景 |
|---|---|
| 实时感知 | QPS 突然掉底、连接数打满,立刻知道 |
| 故障预警 | Buffer Pool 命中率下降,提前扩容 |
| 排障加速 | 出问题时不用"我觉得慢了",直接看指标 |
| 容量规划 | 过去三个月 QPS 趋势,决定什么时候扩容 |
数据这东西不会说谎。嘴上说"不慢"没用,监控图表才说了算。
二、监控的五维指标体系
搞监控第一件事不是选工具,而是搞清楚该看什么。我把 MySQL 的核心指标分成五个维度:
🧠 维度 1:资源使用
| 指标 | 含义 | 告警阈值参考 |
|---|---|---|
| CPU 使用率 | MySQL 进程 CPU 占用 | > 80% 持续 5 分钟 |
| 内存使用 | InnoDB Buffer Pool 占用 | 实际使用 > 可用内存 90% |
| 磁盘 IO | 每秒读写次数 IOPS | 写 IO 延迟 > 20ms |
| 磁盘空间 | 数据目录可用空间 | < 20% |
| 网络吞吐 | 每秒收发流量 | 接近带宽上限 |
这些指标别在 MySQL 里查,用系统命令更快:
bash
# CPU
top -p $(pgrep mysqld) -n1
# 内存
free -h
# 磁盘 IO
iostat -x 1 3
# 磁盘空间
df -h /var/lib/mysql
🧠 维度 2:连接与线程
sql
-- 当前连接数 vs 最大连接数
SHOW VARIABLES LIKE 'max_connections';
SHOW STATUS LIKE 'Threads_connected';
-- 查看连接来源和状态
SELECT user, host, db, command, time, state
FROM information_schema.processlist
WHERE command != 'Sleep'
ORDER BY time DESC;
连接池满了最常见的问题------用户报"无法连接数据库",大概率是连接数被打满。
🧠 维度 3:查询性能
sql
-- QPS 近似计算(两次查询间隔内的差值)
SHOW STATUS LIKE 'Questions';
SHOW STATUS LIKE 'Uptime';
-- 慢查询数量
SHOW STATUS LIKE 'Slow_queries';
-- 全表扫描次数
SHOW STATUS LIKE 'Select_scan';
关注三个关键指标:
- QPS 突降 → 可能有锁等待
- Slow_queries 飙升 → SQL 性能退化或缺少索引
- Select_scan 增长 → 全表扫描增多
🧠 维度 4:InnoDB 引擎
sql
-- Buffer Pool 命中率(核心指标!)
SHOW STATUS LIKE 'Innodb_buffer_pool_read%';
-- 公式:1 - (Innodb_buffer_pool_reads / Innodb_buffer_pool_read_requests) × 100%
-- 目标:> 99%
-- 行锁等待
SHOW STATUS LIKE 'Innodb_row_lock_waits';
SHOW STATUS LIKE 'Innodb_row_lock_time';
-- 脏页比例
SHOW STATUS LIKE 'Innodb_buffer_pool_pages%';
Buffer Pool 命中率是我最关注的指标之一。低于 98% 说明内存不够用了,该扩了。
🧠 维度 5:主从同步
sql
SHOW SLAVE STATUS\G
-- 关注两个字段:
-- Seconds_Behind_Master(延迟)
-- Slave_IO_Running / Slave_SQL_Running(必须都是 Yes)
三、三层工具选型
🟢 新手级:PMM(Percona Monitoring and Management)
PMM 是 Percona 开源的监控平台,基于 Prometheus + Grafana,开箱即用。
安装(docker 一把梭):
bash
# 拉取 PMM Server
docker run -d -p 80:80 -p 443:443 \
--name pmm-server \
percona/pmm-server:2
# 在 MySQL 机器上安装 PMM Client
yum install pmm2-client
# 或
apt-get install pmm2-client
# 注册客户端到服务端
pmm-admin config --server-insecure-tls --server-url=https://admin:admin@<pmm-server-ip>
然后刷浏览器打开 PMM 面板,你会看到一个详细的仪表盘------QPS、连接数、Buffer Pool 命中率、慢查询趋势,全在里面。
🌐 进阶级:搭建你自己的 Grafana 面板
PMM 好用,但如果你已经有 Prometheus 体系,自己搭一套更灵活。
架构:
MySQL → mysqld_exporter → Prometheus → Grafana
步骤 1:安装 mysqld_exporter
bash
# 创建监控用户
CREATE USER 'exporter'@'%' IDENTIFIED BY 'password';
GRANT PROCESS, REPLICATION CLIENT, SELECT ON *.* TO 'exporter'@'%';
# 安装运行
wget https://github.com/prometheus/mysqld_exporter/releases/latest
./mysqld_exporter --mysqld.username=exporter --mysqld.password=password
步骤 2:Prometheus 配置
yaml
# prometheus.yml
- job_name: 'mysql'
static_configs:
- targets: ['your-mysql-host:9104']
步骤 3:Grafana 仪表盘
Grafana 有现成的 MySQL 仪表盘模板:
- Dashboard ID: 7362(MySQL Overview)
- Dashboard ID: 9623(MySQL InnoDB Metrics)
导入就能用,不用从零画图。
🔧 兜底级:纯 SQL 脚本
不是所有环境都能装监控工具。开发环境、内网测试库有时候只能自己跑 SQL 看:
sql
-- 一键快照脚本(适合做定时任务)
SELECT NOW() AS snapshot_time;
SELECT '--- QPS ---' AS indicator;
SELECT ROUND(QUESTIONS / UPTIME, 2) CURRENT_QPS,
ROUND(QUESTIONS / UPTIME, 2) AVG_QPS
FROM (
SELECT VARIABLE_VALUE AS QUESTIONS FROM performance_schema.global_status WHERE VARIABLE_NAME='Questions'
) q,
(
SELECT VARIABLE_VALUE AS UPTIME FROM performance_schema.global_status WHERE VARIABLE_NAME='Uptime'
) u;
SELECT '--- Buffer Pool 命中率 ---' AS indicator;
SELECT
CONCAT(ROUND((1 - reads / requests) * 100, 2), '%') AS buffer_hit_rate
FROM (
SELECT
(SELECT VARIABLE_VALUE FROM performance_schema.global_status WHERE VARIABLE_NAME='Innodb_buffer_pool_reads') AS reads,
(SELECT VARIABLE_VALUE FROM performance_schema.global_status WHERE VARIABLE_NAME='Innodb_buffer_pool_read_requests') AS requests
) t;
SELECT '--- 连接数 ---' AS indicator;
SELECT
(SELECT VARIABLE_VALUE FROM performance_schema.global_status WHERE VARIABLE_NAME='Threads_connected') AS current,
(SELECT VARIABLE_VALUE FROM performance_schema.global_variables WHERE VARIABLE_NAME='max_connections') AS max;
放到 crontab 里每 5 分钟跑一次,输出到文件,自己整理看趋势。
四、告警规则怎么设?
有监控没告警,等于闭着眼睛开车。生产环境最必要的几条告警:
| 告警项 | 条件 | 级别 |
|---|---|---|
| 连接数过多 | 当前连接 > 最大连接 × 0.8 | P1(紧急) |
| 慢查询骤增 | 5 分钟内慢查询 > 50 | P2(重要) |
| Buffer Pool 命中率下降 | < 95% 持续 10 分钟 | P2(重要) |
| 磁盘空间不足 | < 10% 可用 | P1(紧急) |
| 主从延迟 | > 10 秒持续 5 分钟 | P2(重要) |
| QPS 突降 | 下降 > 50% 持续 3 分钟 | P1(紧急) |
告警通知渠道
- P1 → 短信 + 电话 + IM 群通知
- P2 → IM 群通知 + 邮件
别把所有告警都设成 P1,不然会被"狼来了"效应淹没。
五、监控实战 checklist
这是我学监控的计划,按这个顺序来对新手友好:
Phase 1:先看(第 1 周)
bash
# 每天跑一遍,感受数据库的"脉搏"
SHOW STATUS;
SHOW ENGINE INNODB STATUS\G
SHOW PROCESSLIST;
不用监控工具,每天手动跑几次这些命令,感受一下 QPS、连接数、慢查询的变化。先建立"手感"。
Phase 2:再看(第 2-3 周)
- 安装 PMM,导入默认仪表盘
- 学会看 QPS 趋势图、慢查询列表
- 每天看一眼 Buffer Pool 命中率
Phase 3:会报警(第 4 周)
- 配置连接数告警(P1)
- 配置慢查询告警(P2)
- 确认告警通道畅通
Phase 4:能排障(持续)
- 梳理常见性能问题的监控排查路径
- 把排查经验写成 SOP
六、我的排查 SOP:三步定位法
当告警响起,按这三步来:
第一步:全局扫一眼
QPS ↓ 50% → 继续 ↓
连接数 ↑ 300% → 连接池打满 → 可能是慢查询导致连接堆积
慢查询 ↑ 10x → 确认!有慢查询 → 进入第二步
第二步:定位慢查询元凶
sql
-- 查当前正在跑的慢 SQL
SELECT
trx_mysql_thread_id AS thread_id,
trx_query AS current_sql,
TIMESTAMPDIFF(SECOND, trx_started, NOW()) AS running_seconds
FROM information_schema.innodb_trx
WHERE trx_state = 'RUNNING'
ORDER BY running_seconds DESC;
-- 或者从慢查询日志查历史
-- 先确认慢查询日志是否开启
SHOW VARIABLES LIKE 'slow_query_log';
-- 分析最近 50 条慢查询
mysqldumpslow -t 50 /var/lib/mysql/slow.log
第三步:分析慢查询
用 EXPLAIN 看执行计划(这个我们之前的文章详细讲过),定位是全表扫描还是索引没走对。
这套流程在大促值班时用过一次:凌晨 2 点 QPS 掉底告警,顺着三步走,3 分钟定位到一个缓存过期导致的 full join,扩容后恢复正常。
七、今日学习心得
- 监控不是装完工具就完事,指标体系设计比工具重要
- 五个维度(资源/连接/查询/引擎/主从)覆盖 90% 的性能问题
- PMM 适合新手快速上手,Prometheus + Grafana 适合有基础的自己定制
- 告警要分级,别把 P2 的事设成 P1
- 先建立手感,再上工具------顺序很重要
👋 我是 数据库小学妹 一个用设计师思维学数据库的转行人。我们一起,用监控让数据库问题早发现、早解决!💕
本文示例基于 MySQL 8.0 + InnoDB。不同环境配置可能有差异,请结合实际调整。