MySQL保证主备一致
保证主备一致
在状态1中,虽然节点B没有被直接访问,但是我依然建议你把节点B(也就是备库)设置成只读(readonly)模式。这样做,有以下几个考虑:
- 有时候一些运营类的查询语句会被放到备库上去查,设置为只读可以防止误操作;
- 防止切换逻辑有bug,比如切换过程中出现双写,造成主备不一致;
- 可以用readonly状态,来判断节点的角色。
同步完整流程:
一个事务日志同步的完整过程是这样的:
- 在备库B上通过change master命令,设置主库A的IP、端口、用户名、密码,以及要从哪个位置开始请求binlog,这个位置包含文件名和日志偏移量。
- 在备库B上执行start slave命令,这时候备库会启动两个线程,就是图中的io_thread和sql_thread。其中io_thread负责与主库建立连接。
- 主库A校验完用户名、密码后,开始按照备库B传过来的位置,从本地读取binlog,发给B。
- 备库B拿到binlog后,写到本地文件,称为中转日志(relay log)。
- sql_thread读取中转日志,解析出日志里的命令,并执行。
binlog的格式:
- statement:当binlog_format=statement时,binlog里面记录的就是SQL语句的原文。
- row:row格式的binlog里没有了SQL语句的原文,而是替换成了两个event:Table_map(用于说明接下来要操作的表是test库的表t)和Delete_rows(用于定义删除的行为)。
- mixed:mixed格式可以利用statment格式的优点,同时又避免了数据不一致的风险。
上面主要是针对M-S结构,但实际生产上使用比较多的是双M结构,双M结构还有一个循环复制的问题需要解决。
如果节点A同时是节点B的备库,相当于又把节点B新生成的binlog拿过来执行了一次,然后节点A和B间,会不断地循环执行这个更新语句,也就是循环复制了。
双M循环复制解决方案:
- 规定两个库的server id必须不同,如果相同,则它们之间不能设定为主备关系;
- 一个备库接到binlog并在重放的过程中,生成与原binlog的server id相同的新的binlog;
- 每个库在收到从自己的主库发过来的日志后,先判断server id,如果跟自己的相同,表示这个日志是自己生成的,就直接丢弃这个日志。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 goMars的学习随记!
评论