修复方法:1. 增加 binlog_cache_size 参数值,比如设置为 4M 或更大;2. 启用 binlog_stmt_cache_size 参数;3. 将事务拆分成小事务,避免单个事务太大;4. 检查并优化大事务中的 SQL 语句,特别是使用 LIMIT 等分页;5. 重启 MySQL 服务后观察。
原因分析
这个错误 ER_BINLOG_EVENT_WRITE_TO_STMT_CACHE_FAILED 表示写入语句缓存失败。通常发生在 row 格式的 binlog 记录大事务时,binlog_stmt_cache_size 缓存不够用,导致无法写入 binlog 事件缓存。
在 MySQL 5.7+ 版本中,当使用 statement 格式或 mixed 格式的 binlog 时,如果事务中语句过多或数据量大,超过了 binlog_cache_size 或 binlog_stmt_cache_size 的限制,就会报这个错。
详细报错示例
ERROR 1755 (HY000): Write to stmt cache failed, reason: binlog cache size exceeded; size attempted: 67108864; stmt size: 4194304; total cache size: 4194304; cache size limit: 4194304
从报错可以看到,尝试写入的大小超过了缓存限制。
解决方案详解
方法一:修改 my.cnf 配置,添加或增大:
binlog_cache_size = 32M
binlog_stmt_cache_size = 32M
然后重启 MySQL。
方法二:如果是大事务,拆分成多个小事务提交。比如在循环插入时,每 1000 条数据 commit 一次。
方法三:切换 binlog_format 为 ROW,避免 statement 格式的缓存问题,但注意 ROW 格式 binlog 文件会更大。
预防措施
监控 binlog 使用情况,使用 SHOW GLOBAL STATUS LIKE 'Binlog_cache%'; 查看缓存命中率,如果 miss 太多,就需要调大参数。
FAQ:
Q: 这个错误只在 statement 格式下出现吗?
A: 不,主要在 mixed 和 statement 格式下,大事务容易触发。
Q: 增大缓存大小会有什么风险?
A: 会增加内存使用,如果服务器内存小,可能导致 OOM。
Q: 如何查看当前 binlog_cache_size 值?
A: 执行 SHOW VARIABLES LIKE 'binlog_cache_size';
Q: 修复后还会复发怎么办?
A: 优化业务代码,减少大事务发生。