聊聊 MySQL 主从复制的几种复制方式,上岸蚂蚁金服
MySQL 的复制默认是异步的,主从复制至少需要两个 MYSQL 服务,这些 MySQL 服务可以分布在不同的服务器上,也可以在同一台服务器上。
MySQL 主从异步复制是最常见的复制场景。数据的完整性依赖于主库 BINLOG 的不丢失,只要主库的 BINLOG 不丢失,那么就算主库宕机了,我们还可以通过 BINLOG 把丢失的部分数据通过手工同步到从库上去。
注意:主库宕机的情况下,DBA 可以通过 mysqlbinlog 工具手工访问主库 binlog,抽取缺失的日志并同步到从库上去;也可以通过配置高可用 MHA 架构来自动抽取缺失的数据补全从库,或者启用 Global Transaction Identifiers(GTID)来自动抽取缺失 binlog 到从库。
MySQL 在 BINLOG 中记录事务(或 SQL 语句),也就是说对于支持事务的的引擎(例如 InnoDB)来说,每个事务提交时都需要写 BINLOG;对于不支持事务的引擎(例如 MyISAM)来说,每个 SQL 语句执行完成时,都需要些 BINLOG。为了保证 Binlog 的安全,MySQL 引入 sync_binlog 参数来控制 BINLOG 刷新到磁盘的频率。
show variables like 'sync_binlog';
在默认情况下,sync_binlog=1,表示事务提交之前,MySQL 都需要先把 BINLOG 刷新到磁盘,这样的话,即使出现数据库主机操作系统崩溃或者主机突然掉电的情况,系统最多损失 prepared 状态的事务;设置 sync_binlog=1,尽可能保证数据安全。
sync_binlog=0,表示 MySQL 不控制 binlog 的刷新,由文件系统自己控制文件缓存的刷新。
sync_binlog=N,如果 N 不等于 0 或者 1,刷新方式同 sync_binlog=1 类似,只不过此时会延长刷新频率至 N 次 binlog 提交组之后。
以上是传统的异步复制,在 MySQL5.7 的并行复制技术(也称多线程复制)到来之前,为人诟病最多的还是效率问题,slave 延迟是一个顽疾,虽然之前已经出现了 schema 级别的并行复制,但实际效果并不好。
多线程复制
在 MySQL5.7 中,带来了全新的多线程复制技术,解决了当 master 同一个 schema 下的数据发生了变更,从库不能并发应用的问题,同时也真正将 binlog 组提交的优势充分发挥出来,保障了从库并
发应用 Relay Log 的能力。
在 MySQL8.0 中,多线程复制又进行了技术更新,引入了 writeset 的概念,而在之前的版本中,如果主库的同一个会话顺序执行多个不同相关对象的事务,例如,先执行了 Update A 表的数据,又执行了 Update B 表的数据,那么 BINLOG 在复制到从库后,这两个事务是不能并行执行的,writeset 的到来,突破了这个限制。
增强半同步复制
前面介绍的复制是异步操作,主库和从库的数据之间难免会存在一定的延迟,这样存在一个隐患:当在主库上写入一个事务并提交成功,而从库尚未得到主库的 BINLOG 日志时,主库由于磁盘损坏、内存故障、断电等原因意外宕机,导致主库上该事务 BINLOG 丢失,此时从库就会损失这个事务,从而造成主从不一致。
为了解决这个问题,从 MySQL5.5 开始,引入了半同步复制,此时的技术暂且称之为传统的半同步复制,因该技术发展到 MySQL5.7 后,已经演变为增强半同步复制(也成为无损复制)。在异步复制时,主库执行 Commit 提交操作并写入 BINLOG 日志后即可成功返回客户端,无需等待 BINLOG 日志传送给从库,如图所示。
评论