需求
公司内部有几十套基于传统复制的MySQL主从实例,而且binlog的格式都是STATEMENT格式。在接手这些MySQL主从实例之后就有考虑过想将binlog格式更改成ROW格式。而这次则是因为我们elk上面一个第三方工具需要解析和监听binlog信息,并且只能解析ROW格式的binlog,借此机会正好将公司部分MySQL主从复制实例的binlog格式更改成ROW格式。
ROW和STATEMENT比对
- row格式
- 优点:就是能够完全保证主从数据的一致性,不会出现因为在SQL中使用MySQL自带的函数导致数据不一致的现象。例如:当使用now()函数的时候,可能因为从库延时的问题导致时间的数据不一致。线上是有遇到过这个问题的。
- 缺点:就是会消耗比较大的磁盘空间和磁盘IO;还有一个比较重要的问题就是因为ROW格式是基于每行进行修改的,若是在master执行一个update修改5000行数据,那么slave就会执行5000次修改数据操作,那么这就会带来更严重的主从延迟。(因为我们线上使用的是MySQL5.6,是基于schema的并行复制,并且slave的硬件资源是比master差的)
- statement格式
- 优点:就是消耗较少的磁盘存储和IO。
- 缺点:可能会导致数据不一致,并且在做基于binlog恢复的时候可能会出现数据不一致的现象。
binlog格式变更的难点
虽然binlog变更是可以进行在线修改的,但是由于MySQL的master上面存在许多的长链接,哪怕你动态修改之后,长链接的写入和修改还是旧的binlog格式。在这里最开始有提出过俩个方案:
- 重启master。但是线上业务无法中断,所以无法进行修改。
- kill掉所有的长链接。但是由于长链接太多,一个个去kill掉的话实在是耗费时间和经历,所以也不被认可。
解决方案
最后还是回归到需求本身,关于我们的需求就是需要解析binlog的格式是ROW格式,所以我们最后的方案就是在slave上面修改binlog的格式为ROW格式。(log_slave_updates参数必须在slave上面打开。否则master通过binlog传递到slave上面重放的SQL是不会在slave本地的binlog记录的)
- 但是需要注意的是修改完毕之后要想在slave上面的需要重启启动复制。即stop slave,start slave。否则是不会生效的。
- 还有一个需要注意的是,当slave上面已经修改成了ROW格式的时候,这个时候在将slave的binlog格式修改成STATEMENT格式的话,复制是会报错的,哪怕重新restart slave 也会报错。
原文地址:http://blog.51cto.com/11819159/2113690
时间: 2024-10-15 23:23:07