事情本身不复杂,线索都在日志里。MySQL 5.7 从 STATEMENT 切到 ROW 格式做数据同步,binlog_format 改完当天 binlog 每小时涨 12G,三天就把 500G 的数据盘写满,业务写入报 1041 no space left。
第一反应是「没有配过期时间,日志只增不减」,验证下来不成立。
这类报错背后常见的原因有几处,逐个排除就行。一条批量 UPDATE 影响几万行,ROW 格式会把每一行都记一遍。也可能是binlog_row_image 是 FULL,更新一个字段也把整行前后镜像写进去。
不容易想到的是,从库消费不过来,主库的 binlog 被拖着不能清理。
动手时先看 binlog 的增长速度和保留策略
mysql -e 'SHOW BINARY LOGS' && du -sh /var/lib/mysql/*binlog* | tail -5
接着把行镜像改成 MINIMAL 减少体积
mysql -e "SET GLOBAL binlog_row_image = 'MINIMAL'"
然后清理过期的 binlog 释放空间
mysql -e 'PURGE BINARY LOGS BEFORE DATE_SUB(NOW(), INTERVAL 3 DAY)'
等前面都确认过,再把过期时间写进配置长期生效
echo 'binlog_expire_logs_seconds = 259200' >> /etc/my.cnf
怎么算真的好了,看的是同一批现象。SHOW BINARY LOGS 只剩三天的文件,磁盘使用率降到 50% 以下,从库的 Seconds_Behind_Master 保持在 1 秒内。
容易忽略的是,改成 MINIMAL 之前确认下游同步工具支持,某些工具依赖完整前后镜像;切格式前先在从库链路验证一遍。拖得越久,排查成本越高,因为现场状态会被后续操作覆盖。
