这篇文章给大家分享的是有关MySQL 8.0主从复制模型的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。一、MySQL主从复制模型一切都要从MySQL的主从复制模型开始说起,下图是最经典的MySQL主从复制模型架构图:MySQL复制模型MySQL的主从架构依赖于MySQL Binlog功能,Master节点上产生Binlog并将Binlog写入到Binlog文件中。Slave节点上启动两个线程:一个IO线程,从MySQL上捞取Binlog日志并写入到本地的RelayLog日志;另一个SQL线程,不断从RelayLog日志中读取日志,并解析执行,这样通过在主机和从机上增加几个文件的顺序读写操作,就可以保证所有在主机上执行过的SQL语句都在从机上一摸一样的执行过一遍。复制延迟,指的就是一个事务在Master执行完成以后,要多久以后才能在Slave上执行完成。由于对Binlog文件以及RelayLog文件的读写均为顺序操作,在生产环境中,Slave上的IO线程对Binlog文件的Dump操作是很少产生延迟的。实际上,从MySQL 5.5开始,MySQL官方提供了半同步复制插件,每个事务的Binlog需要保证传输到Slave写入 RelayLog 后才能提交,这种架构在主从之间提供了数据完整性,保证了主机在发生故障后从机可以拥有完整的数据副本。因此,复制延迟通常发生在SQL线程执行的过程中。从架构图上可以看到,最早的主从复制模型中,只有一个线程负责执行Relaylog,也就是说所有在主机上的操作,在从机上是串行回放的。这就带来一个问题,如果主上写入压力比较大,那么从上的回放速度很有可能会一直跟不上主。(除此之外,MySQL的架构决定了Binlog只有在Commit阶段才会写入Binlog文件并Dump给从机,这也导致主从事务必然有执行延迟,这个问题在大事务中体现的特别明显,不过这个问题就不在本文的讨论范围内了)既然主从延迟的问题是单线程回放RelayLog太慢,那么减少主从延迟的方案自然就是提高从机上回放RelayLog的并行度。二、5.7中的并行复制1、Schema级别的并行复制MySQL官方在5.6中引入了一个比较简单并行复制方案,其架构如下:(图片来自姜承尧老师的博客)红色框部分为并行回放的关键,5.6中若开启并行回放的功能,便会启动多个WorkThread ,而原来负责回放的SQLThread会转变成Coordinator角色,负责判断事务能否并行执行并分发给WorkThread。如果事务分别属于不同的Schema,并且不是DDL语句,同时没有跨Schema操作,那么就可以并行回放,否则需要等所有Worker线程执行完成后再执行当前日志中的内容。这种并行回放是Schema级别的并行,如果实例上有多个Schema将会因此收益,而如果实例上只有一个Schema,那么事务将无法并行回放,而且还会因多了分发的操作导致效率略微下降。而在实际应用中,单库多表才是更常见的情况。2、基于Group Commit的并行复制虽然5.6中的并行复制在大多数应用场景中对回放速度的提升不大,但是该架构却成为了后来MySQL并行复制的基础——即在Slave上并行回放RelayLog,SQL线程负责判断能否并行回放,并分配给Work线程回放。5.6 中引入Group Commit技术,是为了解决事务提交的时候需要fsync导致并发性不够而引入的。简单来说,就是由于事务提交时必须将Binlog写入到磁盘上而调用fsync,这是一个代价比较高的操作,事务并发提交的情况下,每个事务各自获取日志锁并进行fsync会导致事务实际上以串行的方式写入Binlog文件,这样就大大降低了事务提交的并发程度。5.6中采用的Group Commit技术将事务的提交阶段分成了Flush、Sync、Commit三个阶段,每个阶段维护一个队列,并且由该队列中第一个线程负责执行该步骤,这样实际上就达到了一次可以将一批事务的Binlog fsync到磁盘的目的,这样的一批同时提交的事务称为同一个Group的事务。Group Commit虽然是属于并行提交的技术,但是却意外解决了从机上事务并行回放的一个难题——即如何判断哪些事务可以并行回放。如果一批事务是同时Commit的,那么这些事务必然不会有互斥的持有锁,也不会有执行上的相互依赖,因此这些事务必然可以并行的回放。因此MySQL 5.7 中引入了新的并行回放类型, 由参数 slave_parallel_type决定,默认值DATABASE将会采用5.6版本中的SCHEMA级别的并行回放,设置为LOGICAL_LOCK则会采用基于GroupCommit的并行回放,同一个Group内的事务将会在Slave上并行回放。为了标记事务所属的组,MySQL 5.7 版本在产生 Binlog 日志时会有两个特殊的值记录在 Binlog Event 中,last_committed 和 sequence_number,其中 last_committed指的是该事务提交时,上一个事务提交的编号,sequence_number是事务提交的序列号,在一个Binlog文件内单调递增。如果两个事务的last_committed值一致,这两个事务就是在一个组内提交的。如上binlog文件中,sequence_number 1-6的事务last_committed都是0 ,因此属于同一个组,可以在slave上并行回放,7-12的last_committed都是6,也属于同一个组,因此可以并行回放。5.7 中引入的基于Logical_Lock极大的提高了在主机并发压力比较大的情况下从机上的回放速度,基本上做到了主机上如何提交的,在从机上如何回放。三、MySQL MGR中的WriteSet虽然如此,在 5.7 中,基于逻辑时钟 Logical_Clock 的并行复制仍然有不尽人意的地方,比如必须是在主上并行提交的事务才能在从上并行回放,如果主上并发压力不大,那么就无法享受到并行复制带来的好处。5.7 中引入了binlog_group_commit_sync_delay和binlog_group_commit_sync_no_delay_count两个参数,通过让Binlog在执行fsync前等待一小会来提高Master上组提交的比率。但是无论如何,从上并行回放的速度还是取决于主上并行提交的情况。MySQL 8.0中引入了一种新的机制来判断事务能否并行回放,通过检测事务在运行过程中是否存在写冲突来决定从机上的回放顺序,这使得从机上的并发程度不再依赖于主机。事实上,该机制在MySQL 5.7.20版本中就已经悄悄的应用了。5.7.20版本引入了一个重要的特性:Group Replication,通过Paxso协议在多个MySQL节点间分发binlog,使得一个事务必须在集群内大多数节点(N/2+1)上提交成功才能提交。为了支持多主写入,MySQL MRG在Binlog分发节点完成后,通过一个Certify阶段来决定Binlog中的事务是否写入RelayLog中。这个过程中,Certify阶段采用的就是WriteSet的方式验证事务之间是否存在冲突,同时,在写入RelayLog时会将没有冲突的事务的last_committed值设置为相同的值。比如在5.7.20中,进行如下操作:以上代码在一个MGR集群中创建了一个数据库和一个InnoDB表,并插入了三条记录。这个时候,查询Primary节点上的Binlog可能会得到如下结果:可以看到,由于是在一个Session中,这些操作按着串行的顺序有着不同的 last_committed,正常情况下,这些BinlogEvent应该在从机上同样以串行的方式回放。我们看一下在MGR集群中的RelayLog情况:有趣的是,在Secondary节点的RelayLog中, 这些事务有着相同的last_committed值,也就是说这些事务在MGR集群中,回放的时候可以以并行的方式回放。MGR中,使用的正是WriteSet技术检测不同事务之间是否存在写免费主机域名冲突,并重规划了事务的并行回放,这一技术在8.0中被移到了Binlog生成阶段,并采用到了主从复制的架构中。四、MySQL 8.0中的并行复制说了这么多,终于讲到了MySQL 8.0 ,通过以上描述,读者应该对MySQL 8.0中并行复制的优化的原理有了一个大致的轮廓。通过基于WriteSet的冲突检测,在主机上产生Binlog的时候,不再基于组提交,而是基于事务本身的更新冲突来确定并行关系。1、相关的MySQL参数在MySQL 8.0中,该版本引入了参数binlog_transaction_depandency_tracking用于控制如何决定事务的依赖关系。该值有三个选项:默认的COMMIT_ORDERE表示继续使用5.7中的基于组提交的方式决定事务的依赖关系;WRITESET表示使用写集合来决定事务的依赖关系;还有一个选项WRITESET_SESSION表示使用WriteSet来决免费主机域名定事务的依赖关系,但是同一个Session内的事务不会有相同的last_committed值。在代码实现上,MySQL采用一个vector
小编给大家分享一下如何有效配置MySQL参数,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!1.获取当前配置参数要优化配置参数,首先要了解当前的配置参数以及运行情况。使用下列命令可以获…