Mysql 主备原理

Mysql 支持互为主从,主库通过binlog 将执行的语句传给从库,具体的执行机构:

   主库上的 dump thread,主库上的 binlog 只有在写入到硬盘之后才能通过 dump thread 传出

     从库上的 IO thread,接收主库的 dump thread 发过来的 binlog 并且生成 relay log,这么一层中间日志

     从库上的 sql thread,执行 relay log 中的语句 

   

值得注意的是 ,从库 会 向主库 验证身份,并且告知 主库 binlog 需要开始 读取的位置, 主库才会通过 dump thread 发送给 io thread

各个从库 请求的位置不一样,得到的最终数据可能不一样,连接上之后,主库会一直传 binlog 内容给 从库,直到没有可以传的内容为止。至此之后,如果再有语句执行,写入 binlog 到 磁盘。

则主库 再通过 dump thread 传给 io thread

binlog 有 三种格式 :

  1. row  这种格式 记录的是关乎主键的,也就是记录 主键 = x 这一行被修改了什么,如果被修改的是多行,则会记录 主键 = x,主键 = y ... 被修改了什么

  2.statement  这种格式 是 单纯记录执行的语句的,但是单纯地记录语句 可能发生不一致的情况,比如主库和从库对于 binlog 的同一条语句选用了 不同索引。

         比如 delete * from table where a > x and b < y , 假设 a 和 b 上都有索引,那么可能主库选择 索引 a, 从库选择 索引 b,删除的列可能不完全相同,导致主从不一致

  3.mixed  这种格式 是上述两种的混合。当记录的是有歧义的语句时候,会使用 row 格式,否则用 statement 格式。也就是 像 2 那样有歧义的话,就会使用 row 格式,而不是 statement

循环复制问题,前面提到,mysql 支持互为主从,那么 binlog 不会在 互为主从的两个数据库之间循环复制吗?

不会,因为数据库会按照 server id 来判断 binlog 是否能被执行

比如 A库 server id = 1,B库 server id = 2, A 和 B 互为主从,互为主从的 库必须 server id 不同

那么 A库产生的 binlog 上 标有 server id = 1, 传给B库,B库执行后产生 binlog,产生的 binlog 的 server id 和 之前的一样, 也就是1

然后再 传给A库 , A库判断 server id 和自己一样,不执行,循环中断。

原文地址:https://www.cnblogs.com/lqlqlq/p/14036398.html