MySQL并发复制系列三:MySQL和MariaDB实现对比

并发复制(Parallel Replication) 系列三:MySQL 5.7 和MariaDB 10的parallelreplication对比

作者:沃趣科技MySQL数据库工程师  麻鹏飞


        经过上两篇关于MySQL/MariaDB 的Binary Log Group Commit的发展历程和enhanced multi-threaded slave的介绍,相信大家对MySQL 基于Binay Log 的replication的原理以及为了解决主备数据复制延迟问题而引入的enhanced multi-threaded slave 功能,支持从库多线程并发回放主库提交的事务有了更深入的了解。同时为了更好的发挥MySQL 5.7/MariaDB 10 并发复制的性能,两个版本都在主库Binary Log Group Commit的阶段做了更加深入的优化。

        无论是MySQL还是MariaDB在Binary Log Group Commit优化的目的都是:使高并发下的事务尽可能的在同一个时间点提交,然后用一次fsync()的操作将这一组的Binary log缓存的数据写入磁盘。当并发事务可以在同一个时间提交,说明每个线程所执行的事务之间没有锁冲突(如果有锁冲突,并发的事务将无法在同一个时刻提交),那么意味着这一组并发提交的事务在slave机器上能并发重放主库提交的事务,所以我们只需要在master机器对二进制日志进行Group Commit的时候标记上组提交相关信息,slave机器就可以安全的并发执行主库提交的事务。

我们来看一个例子:

事务T1、T2(starttransaction)开始事务,落后于事务T3、T4的(start transaction)开始时间,但是这一组事务都在C(commit)时间点提交事务,所以这一组事务(T1、T2、T3、T4)将在master机器上进行BinaryLog group Commit,然后该二进制日志推送到slave机器上时可以并发执行这一组被标记的事务。

原理:

       从上面的例子可以看出,并发线程执行不同的事务只要在同一时刻能够commit(说明线程之间没有锁冲突),那么master节点就可以将这一组的事务标记并在slave机器上安全的进行并发重放主库提交的事务。所以尽可能的使所有线程能在同一时刻提交可以极大的提高slave机器并发执行事务的数量使主备数据同步。

在上一篇文章提到过:MySQL/MariaDB开启Binary Log日志后使二进制日志写入顺序和存储引擎提交顺序保持一致,Binary Log Group Commit分为三个过程

1: Binary Log Group Commit 三个阶段

在 Flush stage:所有已经注册线程都将写入binary log缓存

在Sync stage :binary log缓存的数据将会sync到磁盘,当sync_binlog=1时所有该队列事务的二进制日志缓存永久写入磁盘

在 Commit stage:    leader根据顺序调用存储引擎提交事务。

那么为了使更多的并发线程事务能够视为在同一个时刻commit即在Sync阶段(调fsync()把binary log文件系统缓存日志永久刷入磁盘文件)master机器标记并发提交的事务为同一组事务的信息写入binary log日志中。我们可以在Flush Stage将注册为leader的线程带领更多的follower线程到Sync stage进行一次fsync()的操作,来增加Binary Log Group Commit的数量。

如下图:

       当前MySQL/MariaDB数据库实例上运行三个线程分别提交T1、T2、T3事务,T1事务的线程率先提交进入第一阶段Flush stage队列,发现该队列是空队列故注册成leader,与此同时T2事务进入Flush stage成为该队列的follower等待leader调配,事务T1的leader带领T2事务进入Sync stage进行一次fsync()操作那么T1、T2在binary log进行一次group commit在二进制日志内标记了这一组事务。之后T3线程的事务随后进入了binary log提交的过程。

2: 组提交过程

MariaDB 10通过@@binlog_commit_wait_count and@@binlog_commit_wait_usec 两个参数设置,既事务commit阶段的时候至少等binlog_commit_wait_usec毫秒直到有binlog_commit_wait_count个数时进行一次组提交,来提高每组事务中的事务数量,并可以通过查询状态变量@@binlog_commit和@@binlog_group_commit来查参数来查看当前binary log group commit比例。

 MySQL5.7通过引入 binlog_group_commit_sync_delay和 binlog_group_commit_sync_no_delay_count参数即提高binary log组提交并发数量,既MySQL等待binlog_group_commit_sync_delay毫秒的时间直到binlog_group_commit_sync_no_delay_count个数时进行一次组提交。

 

实现:

 Binary Log Group Commit在MySQL 5.7和MariaDB 10 中是默认开启不需要配置任何信息,且在binary log中标记的组提交信息依赖于GTID,而MySQL和MariaDB的GTID组成和实现方式不一样,这里我们简单梳理下。

        在MySQL 5.7版本由于Binary Log Group Commit是默认开启的,所以即使你不开启gtid_mode在配置文件中,binary log的内容中同样也有GTID 信息只不过标记的信息是"ANONYMOUS"

>    show binlogevents in 'mysql-bin.000004';截取一段信息

1.  ...............
|
mysql-bin.000004|3571|Anonymous_Gtid|     15112|       3636| SET @@SESSION.GTID_NEXT='ANONYMOUS'          |

2.  | mysql-bin.000004|3636|Query         |     15112|       3712| BEGIN                                       |

3.  | mysql-bin.000004|3712|Rows_query    |     15112|       3763|# INSERT INTO t1 () VALUES ()                |

4.  | mysql-bin.000004|3763|Table_map     |     15112|       3807| table_id:108(db2.t1)                       |

5.  | mysql-bin.000004|3807|Write_rows    |     15112|       3847| table_id:108 flags: STMT_END_F              |

6.  | mysql-bin.000004|3847|Xid           |    15112|       3878| COMMIT /* xid=33*/                          |
.................

>     mysqlbinlog -vvvmysql-bin.00004 | less

1.  #151231 14:34:03 server id 15112 end_log_pos 2408 CRC32 0x5586fe71     Anonymous_GTID  last_committed=6        sequence_number=8

2.  SET @@SESSION.GTID_NEXT='ANONYMOUS'/*!*/;

3.  # at 2408

4.  #151231 14:34:03 server id 15112 end_log_pos 2484 CRC32 0x748efb17     Query   thread_id=11   exec_time=0     error_code=0

5.  SET TIMESTAMP=1451543643/*!*/;

6.  BEGIN

7.  ..

        

MariaDB的GTID同样也是默认开启且GTID是由DomainID、Server ID和transactionSequence Numbe r 组成:
3 MariaDB GTID组成

>    show binlogevents in 'mysql-bin.000003';截取一段信息

1.  .......
|
mysql-bin.000003|  335|Gtid             |     15102|         377| BEGIN GTID 0-15102-64139                     |

2.  | mysql-bin.000003|  377|Table_map        |     15102|        434| table_id:18(test.sbtest1)                  |

3.  | mysql-bin.000003|  434|Write_rows_v1     |    15102|        657| table_id:18 flags: STMT_END_F               |

4.  | mysql-bin.000003|  657|Xid              |     15102|         688| COMMIT /* xid=16*/                          |

5.  | mysql-bin.000003|  688|Gtid             |     15102|         732| BEGIN GTID 0-15102-64140 cid=20              |

6.  | mysql-bin.000003|  732|Table_map        |     15102|        789| table_id:19(test.sbtest6)                  |

7.  | mysql-bin.000003|  789|Write_rows_v1     |    15102|       1012| table_id:19 flags: STMT_END_F               |

8.  | mysql-bin.000003|1012|Xid              |     15102|        1043| COMMIT /* xid=20*/                          |

9.  | mysql-bin.000003|1043|Gtid             |     15102|        1087| BEGIN GTID 0-15102-64141 cid=20              |

10. | mysql-bin.000003|1087|Table_map        |     15102|       1145| table_id:20(test.sbtest12)                 |

11. | mysql-bin.000003|1145|Write_rows_v1     |    15102|       1368| table_id:20 flags: STMT_END_F               |

12. | mysql-bin.000003|1368|Xid              |     15102|        1399| COMMIT /* xid=21*/                          |
......

 

>    mysqlbinlog-vvv mysql-bin.00003  | less

1.    .......

2.    # at 1754

3.  #160104 15:16:46 server id 15102 end_log_pos 1798 CRC32 0x26104c0b     GTID 0-15102-64143 cid=20 trans

4.  /*!100001 SET @@session.gtid_seq_no=64143*//*!*/;

5.  BEGIN

6.  /*!*/;

7.  # at 1798

8.  #160104 15:16:46 server id 15102 end_log_pos 1856 CRC32 0x2c994f5a     Table_map:`test`.`sbtest12` mapped to number 20

9.  # at 1856

10. #160104 15:16:46 server id 15102 end_log_pos 2079 CRC32 0x02b5a694     Write_rows: table id 20flags: STMT_END_F

11.  

12. BINLOG '

13. .........

 

结论:

        MySQL5.7 / MariaDB 10的parallel replication都是基于主库上Binary Log Group Commit。

        MySQL:  主库并发提交的事务group commit写入binary log日志中,当事务被标记的 last_committed=N 的值相同时(通过binlog_group_commit_sync_delay、 binlog_group_commit_sync_no_delay_count参数设置提高并发事务数量),可以在slave节点并发回放主库提交的事务。

    MariaDB:主库并发提交的事务group commit写入binary log日志中,当事务被标记的 cid=N 的值相同时(通过 binlog_commit_wait_count、binlog_commit_wait_usec参数设置提高并发事务数量),可以在slave节点并发回放主库提交的事务。

 

Reference:http://geek.rohitkalhans.com/2013/09/enhancedMTS-deepdive.html


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值