
日常运维中的坑真是防不胜防,不一小心就遇到别人给你挖的坑。想起多年前生产环境中遇到的因经验不足的DBA不知道从哪拷贝的配置文件(据说是当时参加某培训机构视频培训时资料里的模板,真的是误人子弟呀)放在生产环境而导致数据同步中断的故障。起因是其把max_binlog_cache_size设置成有2G,而MySQL早已将此参数的默认值调整的很大了(18446744073709547520,约16EB),实在没想通为何有人会如此修改。
01 故障描述
突然收到告警,MySQL其中一个从库SQL线程停止,查看日志,其中的错误内容如下:
[ERROR] Slave SQL for channel '': Worker 1 failed executing transaction '370e03bf-aa09-11e9-9bd3-e4434b2aa008:248804226' at master log , end_log_pos 2149953254;
Could not execute Update_rows event on table dbname.tbname;
Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage;
increase this mysqld variable and try again, Error_code: 1197;
handler error HA_ERR_RBR_LOGGING_FAILED; the event's master log FIRST, end_log_pos 2149953254, Error_code: 1197
提示得很明显,max_binlog_cache_size参数的值小了。
引发此问题的主库执行了几个很大的事务,且从库开启了并行复制,因此需要更大的max_binlog_cache_size来处理innodb事务。
02 故障处理
处理过程倒是非常简单,该参数可以动态修改,因此直接调整主库及从库的值。因为也确实没必要还原为默认值,毕竟达不到那么大,因此,先将其设置为40GB
mysql> set global max_binlog_cache_size=40*1024*1024*1024;
Query OK, 0 rows affected (0.00 sec)注意:
03 补充原理:max_binlog_cache_size是如何工作的?
要理解这个故障,我们需要了解MySQL记录二进制日志(Binlog)的机制。
为何从库并行复制下更易触发?
在主库上,大事务执行时就会检查 max_binlog_cache_size。如果主库设置得过小,大事务在主库就会执行失败,根本不会记录到Binlog中,也就不会影响到从库。
在本案例中,问题出在从库。当从库启用并行复制(Multi-Threaded Slave)时,多个工作线程(Worker Thread)会并发回放不同的事务。这些工作线程在应用大事务时,同样需要为自己的任务分配Binlog Cache(用于模拟执行,并非真的写Binlog)。此时,从库上的 max_binlog_cache_size限制就生效了。如果从库的该参数值设置得比主库小,一个在主库成功执行的大事务,在从库却可能因缓存不足而应用失败,导致复制中断。
在工作中你又遇到什么坑的问题吗,欢迎留言区留言交流。
关注微信公众号「数据库干货铺」,获取更多数据库运维干货。