24 | MySQL是怎么保证主备一致的?

Page content

24 | MySQL是怎么保证主备一致的?

建议把从库设置成只读模式

  • 有时候一些运营类的查询语句会被放到备库上去查,设置为只读可以防止误操作;
  • 防止切换逻辑有 bug,比如切换过程中出现双写,造成主备不一致;
  • 可以用 readonly 状态,来判断节点的角色。

从库设置为只读会不会影响主从同步

主从同步的线程拥有超级权限,readonly 不起作用

事务日志的同步过程

  • 备库上执行 change master 命令,设置主库的 ip、端口、用户名、密码、binlog文件名、binlog偏移量
  • 备库上执行 start slave 命令开启两个线程 io_thread、sql_thread
  • 主库校验登录信息,并按照备库的请求读取binlog,发送给备库
  • 备库拿到binlog,写入本地文件(relay log),io_thread 线程负责
  • sql_thread 读取中转日志,解析出日志里的命令,并执行

binlog 格式

对于一条删除语句,三种日志格式的记录是不同的 delete from t where a>=4 and t_modified<='2018-11-10' limit 1;

binlog 格式之 statement

记录原 sql 语句。 切日志格式为 statement,执行这条带 limit 的删除语句时会产生 warning,原因是如果主库和从库执行这条语句时选用的索引不同,执行的结果不同

binlog 格式之 row

会记录删除行的具体信息,以及删除行的主键id,不会导致主备结果不一致。

binlog 格式之 mixed

statement 格式有可能导致主备不一致,row 格式很占内存,mixed 格式是一个折中,不会引起主备差异使用 statement 格式,会引起主备不一致使用 row 格式

双 M 结构中的循环复制问题

双 M 结构在切换的时候不用修改主备关系,但是会导致 M1 生成的binlog传到 M2执行过后,M2 又传递给 M1,导致循环依赖问题

解决方案

  • 规定两个库的 server id 必须不同
  • 一个库在重放收到的 binlog时,生成的 binlog 中的 server id 与原 binlog 中的server id相同
  • 每个库在接收到 binlog 时,判断server id,如果与自己的 server id相同则不再重放