sync_binlog =1
semi-sync 流程分析,前提条件
sync_binlog =1
如果非1 的话 很多地方都不一样了
正常流程
1 在图中(1) 完成binlog 写入文件的pageCache
2 在图中(2) 完成binlog sync 的磁盘binlog 文件
3 在图中(3) 完成binlog 的异步发送,把binlog 发送到备库(等待sync完成,更新binlog updte pos,sync_binlog=1的流程)
4 在图中(4) 完成binlog 发送完成的确认信息(此处可以完全确认binlog已经发送到从库)
5 在图中(5) 用户线程被激活,完成第三阶段的事务提交
异常流程分析
1 在图中(1)完成,还未开始图中(2)时宕机,从库肯定没有当前事务,主库不确定是否有。
因写入pageCache的数据,不做sync操作有可能被操作系统做sync操作,导致当前的
Binlog 已经sync到磁盘。
2 在图中(2)完成,还未开始图中(3)(或者当前事务的binlog还未完整的发送到从库
即图中(3)进行了一半)宕机,主库有,从库没有。
3 在图中(3)完成后,还未开始图中(5)宕机,主库肯定有,从库肯定有
- | 宕机点 | 宕机点 | 主库 | 从库 |
---|---|---|---|---|
1 | (1)完成 | (2)未开始 | 不确定 | 无 |
2 | (2)完成 | (3)未开始或 完成一半 | 有 | 无 |
3 | (3)完成 | 4完成或者未完成 | 有 | 有 |
在4完成前无法确定3是否完成,3 ,4 为异步线程
sync_binlog != 1
semi-sync 流程分析,前提条件
sync_binlog != 1
正常流程
1 在图中(1) 完成binlog 写入文件的pageCache
2 在图中(2) 完成binlog 的异步发送,把binlog 发送到备库(flush binlog 完成,更新binlog updte pos,sync_binlog !=1的流程)
3 在图中(3) 完成binlog sync 的磁盘binlog 文件
4 在图中(4) 完成binlog 发送完成的确认信息(此处可以完全确认binlog已经发送到从库,也可能ack在(3)步之前就到主库了)
5 在图中(5) 用户线程被激活,完成第三阶段的事务提交
异常流程分析
1 在图中(1)完成,还未开始图中(2)时宕机,从库肯定没有当前事务,主库不确定是否有。
因写入pageCache的数据,不做sync操作有可能被操作系统做sync操作,导致当前的
Binlog 已经sync到磁盘。
2 在图中(2)完成,还未开始图中(3)(或者当前事务的binlog还未完整的发送到从库
即图中(3)进行了一半)宕机,主库有,从库没有。
3 在图中(3)完成后,还未开始图中(5)宕机,主库肯定有,从库肯定有
- | 宕机点 | 宕机点 | 主库 | 从库 |
---|---|---|---|---|
1 | (1)完成 | (2)未开始 | 不确定 | 无 |
2 | (2)完成或者完成一半 | (3)未开始 | 不确定 | 不确定 |
3 | (3)完成 | 4完成或者未完成 | 有 | 有 |
在4完成前无法确定2是否完成,2 ,4 为异步线程
主从报文正常流程
1> 发送报文格式
报文头为3字节的长度,1字节的校验位 ( 0~3位)
第4~6 为semi-sync 添加的报文头 第4位为空不用 第5位校验码 0xef 第6位要求
从库是否返回应答报文(即file_pos 与 file_name)0 不返回应答1 返回应答
第7字节开始为binlog的内容
2> 应答报文为固定格式
报文头为3字节的长度,1字节的校验位 (0~3位)
第4位校验码 0xef
第5~12 为binlog的偏移大小 8字节
第13~28 为binlog文件名(当binlog文件为mysql-bin.000001格式时,16字节的长度)
3> 主库的ack线程只收报文,不发报文,从库仅仅发送应答报文。目前的情况是ack线程通过读取4字节的头,确定后续报文的长度。即每次都是固定的读取29字节
不断的确认报文,从库连续不断的发送29字节的报文,主从之间无确认。