被记大过了,一个操作把MySQL主从复制整崩了……( 二 )


被记大过了,一个操作把MySQL主从复制整崩了……

文章插图
根据sql,分析了下,这个表正好有个blob字段,统计了下blob字段总合大概有3个G大小,然后我们业务上有个导入操作,这是一个非常大的事务,会频繁更新这表中记录的更新时间,导致生成binlog非常大 。
问题: 明明只是简单的修改更新时间的语句,压根没有动blob字段,为什么生产的binlog这么大?因为生产的binlog采用的是row模式 。
五、binlog的模式
binlog日志记录存在3种模式,而生产使用的是row模式,它最大的特点,是很精确,你更新表中某行的任何一个字段,会记录下整行的内容,这也就是为什么blob字段都被记录到binlog中,导致binlog非常大 。此外,binlog还有statement和mixed两种模式 。
1.STATEMENT模式 ,基于SQL语句的复制
  • 优点:不需要记录每一行数据的变化,减少binlog日志量,节约IO,提高性能 。
  • 缺点:由于只记录语句,所以,在statement level下 已经发现了有不少情况会造成MySQL的复制出现问题,主要是修改数据的时候使用了某些定的函数或者功能的时候会出现 。
2.ROW模式,基于行的复制
5.1.5版本的MySQL才开始支持,不记录每条sql语句的上下文信息,仅记录哪条数据被修改了,修改成什么样了 。
  • 优点:binlog中可以不记录执行的sql语句的上下文相关的信息,仅仅只需要记录那一条被修改 。所以rowlevel的日志内容会非常清楚的记录下每一行数据修改的细节 。不会出现某些特定的情况下的存储过程或function,以及trigger的调用和触发无法被正确复制的问题 。
  • 缺点:所有的执行的语句当记录到日志中的时候,都将以每行记录的修改来记录,会产生大量的日志内容 。
3.MIXED模式
从5.1.8版本开始,MySQL提供了Mixed格式,实际上就是Statement与Row的结合 。
在Mixed模式下,一般的语句修改使用statment格式保存binlog 。如一些函数,statement无法完成主从复制的操作,则采用row格式保存binlog 。
六、总结
最终分析下来,我们定位到原来是由于大事务+blob字段大致binlog非常大,最终我们采用了修改业务代码,将blob字段单独拆到一张表中解决 。所以,在设计开发过程中,要尽量避免大事务,同时在数据库建模的时候特别考虑将blob字段独立成表 。
作者丨JAVA旭阳
来源丨公众号:JAVA旭阳(ID:javaxuxukkkk)
dbaplus社群欢迎广大技术人员投稿,投稿邮箱:editor@dbaplus.cn
关于我们
dbaplus社群是围绕Database、BigData、AIOps的企业级专业社群 。资深大咖、技术干货,每天精品原创文章推送,每周线上技术分享,每月线下技术沙龙,每季度Gdevops&DAMS行业大会 。




推荐阅读