异步复制
1、主库不会主动的向从库发送消息 而是等待从库的IO线程建立连接 2、主库创建binlog dump线程 3、把binlog event发送给从库的IO线程
同步过程:处理请求
主库在执行完自己的事务 记录完binlog之后就会直接返回 不会与客户端确认任何结果
异步:主从复制
后续由binlog dump线程异步的读取binlog 然后发送给从库
同步复制
主库执行一个事务 那么主库必须等待所有的从库全部执行完事务返回commit之后 才能给客户端返回成功
注:
主库会直接提交事务 而不是等待所有从库返回之后再提交 MySQL只是延迟了对客户端的返回 并没有延后事务的提交
劣势
如果有某个从库复制线程执行的慢 那么对客户端的响应也会慢很多
半同步复制
半同步相对于同步的区别
同步需要等待所有的从库commit 而半同步只需要一个从库commit就可以返回了 如果超过默认的时间仍然没有从库commit 就会切换为异步模式再提交 客户端也不会一直去等待了 因为即使后面主库宕机了 也能至少保证有一个从库节点是可以用的 此外还减少了同步时的等待时间
复制中数据的一致性
主库的binlog dump去读取binlog 然后从库的I/O线程去读取、写入Relay Log 进而从库的SQL线程再读取Relay Log进行重放
异常场景如何保障数据的一致性
- I/O线程复制到一半突然挂掉
- 复制到一半主库宕机
从库IO线程主要做2个操作
- 同步主库的binlog
- 往relay log中记录
relay-log.info文件记录2个操作的进度
往relay-log.info文件中记录 当前从库正在复制的binlog 和写入的Relay Log的Pos
relay-log.info文件存在的意义
当从库意外重启之后 就会重新读取文件 从上次复制的地方开始继续复制
relay log存储载体进化史
5.5及之前只能存放磁盘文件中 比如设置参数sync_relay_log_info=5 即往relay-log.info文件写了5个事务之后 就会把该文件内容刷新到磁盘
如果在刷入磁盘之前 从库挂了
那么就会有一部分事务丢失 重启从库 就会发现SQL线程实际执行到位置和数据库记录的不一致 数据一致性的问题就这么产生了 比如SQL线程实际执行到pos=100的位置 还有5个事务准备刷入磁盘 但从库挂了 数据库仅记录到pos=95的位置
为了解决这一问题 所以relaylog也可以用table方式记录
将复制的进度放在系统的mysql.slave_relay_log_info表里去 并且把更新进度、SQL线程执行用户事务绑定成一个事务执行
即使slave宕机了 也可以通过MySQL内建的崩溃恢复机制来使 实际执行的位置和数据库保存的进度恢复到一致
半同步复制数据一致性问题
半同步复制 主库会先提交事务 然后等待从库的返回 再将结果返回给客户端 但是如果在主库等待的时候 从库挂了 从库重启之后却没有这个数据
MySQL5.6处理方式
主库先提交事务 等待从库返回结果再通知客户端
MySQL 5.7处理方式
主库先不提交事务 等待某一个从库返回了结果之后 再提交事务 如果从库在没有任何返回的情况下宕机了 master这边也无法提交事务 主从仍然是一致的