问题出现得很突然,日志倒是留得挺全。备份脚本直接用 mysqldump 默认参数,凌晨两点全表加读锁,持续十分钟。蜘蛛正好在两点到两点半抓取,那批请求全部超时。
刚开始盯着「前台没有页面缓存,读请求全部落到数据库」,折腾了半个多小时,排掉了。
这类报错背后常见的原因有几处,逐个排除就行。mysqldump 默认带锁表参数,整库进入只读。少数情况下是备份时间与抓取高峰重叠。
不容易想到的是,备份不限速,磁盘 IO 被打满拖慢查询。
先改用一致性快照备份
mysqldump --single-transaction --quick --skip-lock-tables db > dump.sql
随后把备份挪到抓取最少的时段
给备份加 IO 限速
ionice -c2 -n7 nice -n19 mysqldump --single-transaction db > dump.sql
回看当晚蜘蛛请求的响应时间
awk '$4 ~ /02:/ {print $request_time}' access.log | sort -nr | head
别只看报错消失,验证要多做一步。备份期间页面响应正常,超时归零,抓取量第二天恢复到日均水平。
这里还有个坑。备份跑成功不代表没影响,锁表参数默认是开着的,改一项就能把十分钟的写锁换成无锁快照。同一份配置在测试环境跑通,不代表线上没事,两边的默认值经常不一样。
