这个坑值得记一笔。每小时整点跑一次全量统计,执行期间接口 P99 从五十毫秒涨到八百毫秒,统计 SQL 扫的是同一张两千万行的订单表,MySQL 8.0 主库。

刚开始盯着「没有只读从库,读写资源混在一起」,折腾了半个多小时,排掉了。

真正麻烦的地方在于,几个原因的现象几乎一样。统计 SQL 没有时间范围,每次都是全表扫描;跑在主库上,和业务抢 buffer pool;统计期间产生大量脏页,刷盘拖慢写入。

先确认统计期间的扫描行数

mysql -e "select digest_text,sum_rows_examined from performance_schema.events_statements_summary_by_digest order by sum_rows_examined desc limit 5\G"

随后把统计改成按时间增量

mysql -e "select count(*) from orders where created_at >= curdate() - interval 1 day;"

迁到只读从库执行

mysql -h 10.0.0.22 -e "select count(*) from orders where created_at >= curdate();"

错峰到低峰并观察主库 P99

mysql -e "select now(),count(*) from information_schema.processlist;"

怎么算真的好了,看的是同一批现象。统计任务迁走后主库 P99 回到六十毫秒以内,统计结果仍按时产出,从库延迟在两秒以内。

补一句。报表统计一律走从库或者离线库,主库只承担交易;增量统计比全量少一个数量级的扫描量。线上能稳定复现的问题都不算难,难的是只在大流量下才出现的那种。

作者 9823189