一文讲解MySQL的主从复制
阿粉在前面的几篇文章中,说了索引的分析,索引的原理,以及慢查询应该怎么去做合理的优化,接下来阿粉也给大家说说这个 MySQL 的组从复制到底是个怎么回事。
主从模式
MySQL主从模式是指数据可以从一个MySQL数据库服务器主节点复制到一个或多个从节点。MySQL 默 认采用异步复制方式,这样从节点不用一直访问主服务器来更新自己的数据,从节点可以复制主数据库 中的所有数据库,或者特定的数据库,或者特定的表。
mysql主从复制用途:
- 实时灾备,用于故障切换(高可用)
- 读写分离,提供查询服务(读扩展)
- 数据备份,避免影响业务(高可用)
主从部署必要条件:
- 从库服务器能连通主库
- 主库开启binlog日志(设置log-bin参数)
- 主从server-id不
上面这些就是我们如果想要部署一套属于自己的 MySQL 的主从复制时,需要的条件,那么主从复制都是什么原理呢?
主从复制的步骤
主从复制整体分为以下三个步骤:
第一步:主库将数据库的变更操作记录到Binlog日志文件中
第二步:从库读取主库中的Binlog日志文件信息写入到从库的Relay Log中继日志中
第三步:从库读取中继日志信息在从库中进行Replay,更新从库数据信息
上面的是文字描述,
我们再来一张原理图看看:
在上述三个过程中,涉及了Master的BinlogDump Thread和Slave的I/O Thread、SQL Thread,它们的作用如下:
- Master服务器对数据库更改操作记录在Binlog中,BinlogDump Thread接到写入请求后,读取 Binlog信息推送给Slave的I/O Thread。
- Slave的I/O Thread将读取到的Binlog信息写入到本地Relay Log中。
- Slave的SQL Thread检测到Relay Log的变更请求,解析relay log中内容在从库上执行。 上述过程都是异步操作,俗称异步复制,存在数据延迟现象。
但是如果我们这么看主从复制的话,是不是会发现一些问题呢?
MySQL主从复制的问题:
- 主库宕机后,数据可能丢失
- 从库只有一个SQL Thread,主库写压力大,复制很可能延时
一般的,如果我们做了主从复制的话,那么数据库一定出现过复制延迟的情况,如果你没遇到过,说明你没有发现过,但是实际上是肯定有过的,除非你已经想到了如何去解决这个问题了,那么解决这个问题的方式是什么呢?
- 半同步复制---解决数据丢失的问题
- 并行复制----解决从库复制延迟的问题
那么什么是半同步复制,什么是并行复制呢?
半同步复制
为了提升数据安全,MySQL让Master在某一个时间点等待Slave节点的 ACK(Acknowledge character)消息,接收到ACK消息后才进行事务提交,这也是半同步复制的基础。
- 当Master不需要关注Slave是否接受到Binlog Event时,即为传统的主从复制。
- 当Master需要在第三步等待Slave返回ACK时,即为 after-commit,半同步复制(MySQL 5.5引入)。
- 当Master需要在第二步等待 Slave 返回 ACK 时,即为 after-sync,增强半同步(MySQL 5.7引入)。
主库等待从库写入 relay log 并返回 ACK 后才进行Engine Commit。
并行复制
其实 MySQL 的并行复制,每个版本都是不一样的,因为他们的实现原理是不一样的。
MySQL从5.6版本开始追加了并行复制功能,目的就是为了改善复制延迟问题,并行复制称为enhanced multi-threaded slave(简称MTS)。
在从库中有两个线程IO Thread和SQL Thread,都是单线程模式工作,因此有了延迟问题,我们可以采 用多线程机制来加强,减少从库复制延迟。
MySQL5.7版本,基于组提交的并行复制,这个才是真正意义的并行复制,从库的并行复制跟master库的是一致,并行复制基于一个前提,即所有已经处于prepare阶段的事务,都是可以并行提交的。
MySQL8.0版本,基于write-set的并行复制,MySQL会有一个集合变量用来存储事务修改的记录信息(主键哈希值),当新的修改时已提交时,会进行判断是否冲突,不冲突即可合并,这样的并行的颗粒度就到row级别了,并行复制的速度更快
其实如果你想要进行并行复制的话,那么你还需要知道如何去进行并行复制的调优,只有这样,你才能掌握好这个主从复制。
binlog_transaction_dependency_history_size
用于控制集合变量的大小。
binlog_transaction_depandency_tracking
用于控制binlog文件中事务之间的依赖关系,即last_committed值。
transaction_write_set_extraction
用于控制事务的检测算法,参数值为:OFF、 XXHASH64、MURMUR32
master_info_repository
开启MTS功能后,务必将参数master_info_repostitory设置为TABLE,这样性能可以有50%~80%的提升。这是因为并行复制开启后对于元master.info这个文件的更新将会大幅提升,资源的竞争也会变大。
slave_parallel_workers
若将slave_parallel_workers设置为0,则MySQL 5.7退化为原单线程复制,但将 slave_parallel_workers设置为1,则SQL线程功能转化为coordinator线程,但是只有1个worker线程进行回放,也是单线程复制。然而,这两种性能却又有一些的区别,因为多了一次coordinator线程的转发,因此slave_parallel_workers=1的性能反而比0还要差。
这些参数实际上都是非常要掌握的,不然你再设置并行复制的时候,会遇到各种各样的问题,所以你学会了么?
文章参考
《MySQL海量数据优化》
《MySQL必知必会》
《MySQL拍错指南》
文章转载自公众号: Java极客技术