您现在的位置是:烟消火灭网 > 娱乐

监控数据库

烟消火灭网2026-10-17 07:48:47【娱乐】9人已围观

简介凌晨三点,手机震了。不是闹钟,是Zabbix发来的告警:主库活跃连接数飙到4800,CPU 98%。我从床上弹起来,连VPN,敲下第一条命令——show processlist。满屏的查询卡在Send

凌晨三点,监控手机震了。数据不是监控闹钟,是数据Zabbix发来的告警:主库活跃连接数飙到4800,CPU 98%。监控我从床上弹起来,数据连VPN,监控敲下第一条命令——show processlist。数据满屏的监控查询卡在Sending data状态,最久的数据已经跑了47分钟。这是监控上个月真实发生的事。

监控数据库这件事,数据很多人第一反应是监控装个Prometheus,拉几个指标,数据画几张图。监控但真到了出事的时候,你会发现那些漂亮的仪表盘根本救不了命。问题不在于你监控了什么,而在于你监控的东西能不能回答一个具体问题:现在到底哪里堵了?

我见过太多团队把监控做成了面子工程。Grafana上几十个面板,每个都花花绿绿,但值班的人根本不知道哪个指标该先看。有一次去帮朋友排查一个慢查询问题,他们的监控系统采集了200多个指标,唯独没有采集Innodb_row_lock_time_avg。结果呢?一个简单的行锁等待拖垮了整个订单系统,他们花了四个小时才定位到。

别只盯着QPS

QPS这个指标有毒。它涨了你不一定有事,它跌了你也不一定没事。真正要盯的是连接数、活跃线程、锁等待、临时表落盘这几个。尤其是Threads_running,这个值一旦超过CPU核数的两倍,基本就可以准备写故障报告了。我自己的习惯是在每台DB上跑一个每秒钟采集一次的脚本,把Threads_running、Threads_connected、Innodb_row_lock_current_waits写到本地文件,再用Node Exporter的textfile collector吐给Prometheus。别问为什么不直接上mysqld_exporter——它默认15秒的采集间隔,在秒杀场景下什么都抓不到。

慢查询日志也得实时看。不是让你去翻文件,是把它灌到ClickHouse或者Elasticsearch里,按query_time排序,按rows_examined过滤。我设的阈值是:执行超过1秒且扫描行数超过10万的查询,直接告警到钉钉群。有一次抓到一条SELECT * FROM orders WHERE status = 'pending',没走索引,扫了800万行。开发说“就查一下待处理的订单”,他不知道那张表已经累积了三年数据。

监控的粒度决定恢复的速度

说个反直觉的:监控越细,恢复越快。但“细”不是指指标数量,而是指时间粒度。很多云厂商的RDS监控最小粒度是1分钟,这玩意儿在生产事故里跟没有一样。一个死锁从发生到蔓延,30秒就够了。你1分钟才采一次,看到的永远是已经炸了的画面。

所以我在关键业务库上坚持用pt-stalk或者自己写的触发器。当Threads_running超过阈值时,自动抓取show engine innodb status、show full processlist、iostat -x 1 5,存下来。事后复盘的时候,这些快照比任何图表都管用。上个月那次故障,就是靠pt-stalk抓到的现场,发现是某个报表查询没加LIMIT,把buffer pool冲干净了。

还有一点:别忽略操作系统层面的监控。数据库再快,磁盘IO跟不上一律白搭。我习惯把iostat里的%util和await跟MySQL的Innodb_data_reads放在同一张图上看。有一次发现await突然从2ms跳到80ms,但MySQL层面一切正常。查下去发现是RAID卡电池坏了,写策略从WB变成了WT。这种问题,光看数据库指标永远找不到。

最后说个实在的:监控系统本身也会挂。Zabbix的server、Prometheus的TSDB、告警通道,任何一个环节断了,你就成了瞎子。我的做法是搞一个最简单的cron脚本,每五分钟往一个公共的Pastebin写一行时间戳。如果这个Pastebin超过十分钟没更新,说明整个监控链路都死了。这招救过我两次——一次是Prometheus的磁盘满了,一次是告警网关被防火墙规则误杀。

监控数据库不是买一堆工具堆上去就完事。它更像一种习惯:你得知道正常的时候长什么样,才能在异常的时候一眼认出来。那些凌晨三点的告警,不是骚扰,是数据库在跟你说话。听不听得懂,看平时功夫。

很赞哦!(43721)