说到MySQL性能监控,很多开发者和DBA朋友都踩过坑。别问为什么——我见过太多人只盯着“慢查询”这一招,结果等线上炸锅才后悔。今天我把那些血泪经验整理出来,帮你从基础到高阶,一步步把监控体系搭得稳如泰山。咱们不整虚的,就聊真实场景里那些让人头秃的瞬间和解决办法。
一、慢查询日志:入门必学,但别只靠它
1.1 开启慢查询日志
MySQL默认不开启慢查询日志,得自己配置。在my.cnf或my.ini文件里加这几行:
[mysqld]
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 2 # 超过2秒的记录
log_queries_not_using_indexes = 1 # 没走索引的也记下来
重启生效之后,每次有SQL跑超时的都会往日志里塞一条。但注意!这玩意儿是事后诸葛亮,线上出问题了才能回看,没法提前预警。而且日志数据量大了,解析起来像翻山越岭。
1.2 分析慢查询日志工具推荐
- pt-query-digest(Percona Toolkit):神器中的神器,能把一堆慢查询分析成报告,告诉你哪些SQL最拖后腿。用法简单:
pt-query-digest /var/log/mysql/slow.log > report.txt - mysqldumpslow:MySQL自带的小弟,功能弱些,胜在不用装额外包。比如查前10慢:
mysqldumpslow -s t -t 10 /var/log/mysql/slow.log
⚠️ 避坑点:别在生产环境开log_queries_not_using_indexes=1太久!除非你真想制造灾难。这条开着会让日志爆炸,尤其是高并发场景下,几分钟就能占满磁盘。建议临时打开排查问题,搞定立马关掉。
二、实时监控:别让老板等你事后汇报
2.1 为什么要实时?
想象一下:某天晚上9点,用户投诉系统卡成PPT。你点开慢查询日志,发现3小时前就有大量超时记录……这时候只能干瞪眼。而实时监控能像装了雷达一样,发现异常立刻报警。
2.2 常用实时监控方案
(1)Prometheus + Grafana(开源首选)
这是目前最流行的组合。用mysqld_exporter拉取MySQL指标,存到Prometheus里,再用Grafana画看板。配置步骤挺绕,但只要动手一次就熟了。核心关注指标:
Queries_per_second:QPS波动
Slow_queries:慢查询数突增
Threads_connected:连接池是否爆满
示例Grafana面板可以直接搜社区模板,比如编号7318的MySQL监控大盘就很全。
(2)Zabbix(传统派最爱)
如果你公司以前就用Zabbix继续无缝衔接。它支持主动式检查+被动式代理,还能设置触发器自动发邮件/钉钉提醒。比如当uptime < 60s就判定MySQL挂了,赶紧救火。
(3)CloudWatch/AWS RDS Metrics(云用户友好)
如果用阿里云RDS或AWS直接开箱即用,控制台里就有基础监控图表。虽然不如自搭灵活,但对于中小项目足够应付日常需求。
💡 小心陷阱:不要把所有指标都挂到同一个告警通道上!我曾见过同事被50条冗余消息淹没,真问题时反而错过了。记得做分级:严重错误→短信/电话;普通警告→邮件/IM通知。
三、进阶技巧:那些高手才会用的方法
3.1 Performance Schema(内置宝藏)
从MySQL 5.6开始自带的轻量级性能剖析库,比慢查询更细粒度。比如你想看某个锁住了谁、哪个线程等待时间最长,都可以用下面语句查询:
SELECT EVENT_NAME, COUNT_STAR, SUM_TIMER_WAIT
FROM performance_schema.events_waits_summary_by_event_name
ORDER BY SUM_TIMER_WAIT DESC LIMIT 10;
缺点是默认部分功能需启用,且对性能有轻微影响(一般%),但为了诊断值得。
3.2 自定义监控脚本写起来不难
有时候标准化工具不够用,写个Python脚本抓取特定字段就行。比如监控InnoDB缓冲池命中率:
import pymysql
conn = pymysql.connect(host='localhost', user='root', password='pass', db='information_schema')
cursor = conn.cursor()
cursor.execute("SELECT ENGINE='InnoDB' AND Variable_name='Innodb_buffer_pool_pages_total' FROM information_schema.GLOBAL_STATUS")
result = cursor.fetchall()
print(f"Buffer Pool Hit Rate: {1 - float(result[0][1])/float(result[0][0]) * 100:.2f}%")
这类小脚本放在crontab里定时跑,配合简单HTML报表也能做成迷你监控系统。
四、真实案例分享:一次差点翻车的经历
去年负责一个电商大促期间的MySQL稳定性保障,起初一切顺利直到流量高峰来临。当时我们只依赖Grafana上的QPS曲线,突然看到某表写入延迟飙升但无明显错误日志。
后来才发现是因为大批量INSERT触发了主键热点竞争(自增ID集中在同一页)。如果早有Partitioning策略或者改用UUID分散分布,就不会出现这种现象。这次教训让我深刻理解:光看表面数字不够,必须结合执行计划、锁状态、资源瓶颈多维度交叉验证。
所以现在我的团队在做任何变更前,都会先模拟测试其对监控体系的影响,确保不会因为优化引入新的盲区。
五、总结与建议清单
- ✅ 起步阶段:先配好慢查询日志,养成定期review的习惯;
- 🚀 成长期:搭建Prometheus+Grafana实现可视化+自动告警;
- 💼 成熟期:引入Performance Schema深入剖析问题根源,甚至编写定制化探针;
- 🔁 持续迭代:每周审查一次现有监控的有效性,剔除无效项、补充新维度。
记住啊,监控不是为了完成任务摆样子,而是真正能帮你快速定位解决问题的那个“超级助手”。希望这篇指南能让你少走弯路,早日成为别人眼中的“MySQL大神”!
