从库的readonly对super权限的用户是无效的,所以设置为readonly状态的从库仍然可以主从同步。

数据在主从同步的完整流程

image.png
dump_thread:主库中的线程,专门用于服务从库与主库之间维持的长连接,并从主库读取binlog发送给从库。
io_thread:从库中的线程,负责与主库建立连接,接收主库的binlog文件,写到从库的relay_log中。
sql_thread:从库中的线程,负责读取并解析执行relaylog中的命令,完成数据在从库中的同步。sql_thread可以开启多个线程。

binlog的格式

  1. statement格式:记录的SQL语句原文

image.png
statement格式有一个缺陷,会导致命令可能是unsafe的,因为这种格式记录的是SQL语句原文,如果这个SQL在主库和从库执行时,使用的索引不一样,当SQL语句又带有limit等条件时,有可能导致结果是不同的。

  1. row格式:记录操作的主键id。

row格式有一个缺点,很占空间。比如删除10万行数据,row格式要记录10w个主键id记录。
优点:因为记录了全部记录id,所以用来做insert、delete、update的数据恢复时很方便。

  1. mixed格式:前两者的混合

对于没有主从不一致unsafe风险的SQL,使用statement格式来记录binlog,有unsafe就是用row格式。

用binlog恢复数据

用binlog来恢复数据的标准做法:用mysqlbinlog工具解析出完整的binlog,然后将完整的结果整个发送给MySQL执行。不能只把binlog中statement语句直接单独执行,会缺少原SQL执行时刻等信息。

互为主备的循环复制

AB两个库互为主从,这样设置可以节省容灾时的主从关系修改时间。
但是这样操作,按照理解会导致一个写操作的binlog在AB主从之间多次传递复制问题。
MySQL的优化是:

  1. 要求A、B两个库的server id不同,否则不能设置主从关系。
  2. B库接到A库的binlog并在重放过程中,生成的新的binlog中的server id与原binlog中的server id保持相同。
  3. 当B库生成的新的binlog再传递到A库时,A判断到这个binlog的server id与自己相同,就不会再处理这个日志,解决了循环复制问题。

但是如果A库在生产过程中更改了自己的server id,有可能导致一次循环复制。
如果A、B、B’三个库,A库执行了事务trx1,生成binlog传递给B,其中binlog的server id就是A,如果这时B和B’互为主从,binlog就会在B和B’之间产生循环复制。