在状态1中,客户端的读写都直接访问节点A,而节点B是A的备库,只是将A的更新都同步过来,到本地执行。这样可以保持节点B和A的数据是相同的。当需要切换的时候,就切成状态2。这时候客户端读写访问的都是节点B,而节点A是B的备库
在状态1中,虽然节点B没有被直接访问,但是建议把备库节点B,设置成只读模式。有以下几个原因:
把备库设置成只读,还怎么跟主库保持同步更新?
readonly设置对超级权限用户是无效的,而用于同步更新的线程,就拥有超级权限
下图是一个update语句在节点A执行,然后同步到节点B的完整流程图:
备库B和主库A之间维持了一个长连接。主库A内部有一个线程,专门用于服务备库B的这个长连接。一个事务日志同步的完整过程如下:
change master
命令,设置主库A的IP、端口、用户名、密码,以及要从哪个位置开始请求binlog,这个位置包含文件名和日志偏移量start slave
命令,这时备库会启动两个线程,就是图中的io_thread
和sql_thread
。其中io_thread
负责与主库建立连接sql_thread
读取中转日志,解析出日志里的命令,并执行由于多线程复制方案的引入,sql_thread
演化成了多个线程
双M结构:
作者:Java编程宇宙 链接:https://zhuanlan.zhihu.com/p/394921571 来源:知乎 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
节点A和节点B互为主备关系。这样在切换的时候就不用再修改主备关系
双M结构有一个问题要解决,业务逻辑在节点A上更新了一条语句,然后再把生成的binlog发给节点B,节点B执行完这条更新语句后也会生成binlog。那么,如果节点A同时是节点B的备库,相当于又把节点B新生成的binlog拿过来执行了一次,然后节点A和B间,会不断地循环执行这个更新语句,也就是循环复制
MySQL在binlog中记录了这个命令第一次执行时所在实例的server id。因此,可以用下面的逻辑,来解决两个节点间的循环复制问题:
双M结构日志的执行流如下:
作者:Java编程宇宙 链接:https://zhuanlan.zhihu.com/p/394921571 来源:知乎 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
与数据同步有关的时间点主要包括以下三个:
所谓主备延迟,就是同一个事务,在备库执行完成的时间和主库执行完成的时间之间的差值,也就是T3-T1
可以在备库上执行show slave status命令,它的返回结果里面会显示seconds_behind_master
,用于表示当前备库延迟了多少秒
seconds_behind_master的计算方法是这样的:
seconds_behind_master
如果主备库机器的系统时间设置不一致,不会导致主备延迟的值不准。备库连接到主库的时候,会通过SELECTUNIX_TIMESTAMP()函数来获得当前主库的系统时间。如果这时候发现主库的系统时间与自己不一致,备库在执行seconds_behind_master计算的时候会自动扣掉这个差值
网络正常情况下,主备延迟的主要来源是备库接收完binlog和执行完这个事务之间的时间差
主备延迟最直接的表现是,备库消费中转日志的速度,比主库生产binlog的速度要慢
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。