MySQL是怎么保证主备一致的?
MySQL主备的基本原理:
在状态 1 中,客户端的读写都直接访问节点 A,而节点 B 是 A 的备库,只是将 A 的更新都同步过来,到本地执行。这样可以保持节点 B 和 A 的数据是相同的。
当需要切换的时候,就切成状态 2。这时候客户端读写访问的都是节点 B,而节点 A 是 B 的备库。
在状态 1 中,虽然节点 B 没有被直接访问,但是我依然建议你把节点 B(也就是备库)设置成只读(readonly)模式。这样做,有以下几个考虑:
1.有时候一些运营类的查询语句会被放到备库上去查,设置为只读可以防止误操作;
2.防止切换逻辑有 bug,比如切换过程中出现双写,造成主备不一致;
3.可以用 readonly 状态,来判断节点的角色。
你可能会问,我把备库设置成只读了,还怎么跟主库保持同步更新呢?这个问题,你不用担心。因为 readonly 设置对超级 (super) 权限用户是无效的,而用于同步更新的线程,就拥有超级权限。
主要还是通过解析binlog日志来保持主备一致性,binlog日志有三种格式:
- statement。执行sql语句原文,缺点是可能语义在主备有不同的解析方式,引起数据不一致。
- row。将修改前后的信息都记录下来,优点是不会出错,且有完整数据备份,即使不考虑同步的情况,在误操作恢复数据时也能提供原始数据。缺点就是日志较大,现在越多越推崇row格式
- mixed。由MySQL决定,语义无歧意时,使用statement节约空间,其他情况则用row