共计 4446 个字符,预计需要花费 12 分钟才能阅读完成。
传统单线程复制阐明
家喻户晓,MySQL 在 5.6 版本之前,主从复制的从节点上有两个线程,别离是 I / O 线程和 SQL 线程。
- I/ O 线程负责接管二进制日志的 Event 写入 Relay Log。
- SQL 线程读取 Relay Log 并在数据库中进行回放。
以上形式偶然会造成提早,那么可能造成主从节点提早的状况有哪些?
- 1. 主库执行大事务(如:大表构造变更操作)。
- 2. 主库大批量变更(如:大量插入、更新、删除操作)。
- 3.ROW 同步模式下,主库大表无主键频繁更新。
- 4. 数据库参数配置不合理,从节点性能存在瓶颈(如:从节点事务日志设置过小,导致频繁刷盘)。
- 5. 网络环境不稳固,从节点 IO 线程读取 binlog 存在提早、重连状况。
- 6. 主从硬件配置差别,从节点的硬件资源应用达到下限。(比方:主节点 SSD 盘,从节点 SAS 盘)
能够对以上提早起因做个大抵分类。
- 1. 硬件方面问题(包含磁盘 IO、网络 IO 等)
- 2. 配置方面问题。
- 3. 数据库设计问题。
- 4. 主库大批量变更,从节点 SQL 单线程解决不够及时。
总结
剖析以上起因能够看出要想升高主从提早,除了改善硬件方面条件之外,另外就是须要 DBA 关注数据库设计和配置问题,最初就是须要进步从节点的并发解决能力,由单线程回放改为多线程并行回放是一个比拟好的办法,关键点在于如何在多线程复原的前提下解决数据抵触和故障复原地位点的确认问题。
MySQL5.6 基于库级别的并行复制
在实例中有多个数据库的状况下,能够开启多个线程,每个线程对应一个数据库。该模式下从节点会启动多个线程。线程分为两类
Coordinator
和WorkThread
。
- 线程分工执行逻辑
Coordinator
线程负责判断事务是否能够并行执行,如果能够并行就把事务分发给 WorkThread
线程执行,如果判断不能执行,如 DDL
, 跨库操作
等,就期待所有的 worker 线程执行实现之后,再由 Coordinator
执行。
- 要害配置信息
slave-parallel-type=DATABASE
- 计划有余点
这种并行复制的模式, 只有在实例中有多个 DB 且 DB 的事务都绝对忙碌的状况下才会有较高的并行度,然而日常保护中其实单个实例的的事务处理绝对集中在一个 DB 上。通过观察提早能够发现基本上都是基于热点表呈现提早的状况占大多数。如果可能提供基于表的并行度是一个很好办法。
MySQL5.7 基于组提交的并行复制
组提交阐明
简略来说就是在双 1 的设置下,事务提交后即刷盘的操作改为多个事务合并成一组事务再进行对立刷盘,这样解决就升高了磁盘 IO 的压力。详细资料参考
老叶茶馆
对于组提交的阐明推文https://mp.weixin.qq.com/s/rcPkrutiLc93aTblEZ7sFg
一组事务同时提交也就意味着组内事务不存在抵触,故组内的事务在从节点上就能够并发执行,问题在于如何辨别事务是否在同一组中的,于是在 binlog 中呈现了两个新的参数信息last_committed
和 sequence_number
- 如何判断事务在一个组内呢?
解析 binlog 能够发现外面多了
last_committed
和sequence_number
两个参数信息,其中last_committed
存在反复的状况。
sequence_number
# 这个值指的是事务提交的序号,枯燥递增。last_committed
# 这个值有两层含意,1. 雷同值代表这些事务是在同一个组内,2. 该值同时又是代表上一组事务的最大编号。
[root@mgr2 GreatSQL]# mysqlbinlog mysql-bin.0000002 | grep last_committed
GTID last_committed=0 sequence_number=1
GTID last_committed=0 sequence_number=2
GTID last_committed=2 sequence_number=3
GTID last_committed=2 sequence_number=4
GTID last_committed=2 sequence_number=5
GTID last_committed=2 sequence_number=6
GTID last_committed=6 sequence_number=7
GTID last_committed=6 sequence_number=8
- 数据库配置
slave-parallel-type=LOGICAL_CLOCK
- 计划有余点
基于
LOGICAL_CLOCK
的同步有个有余点,就是当主节点的事务忙碌度较低的时候,导致时间段内组提交 fsync 刷盘的事务量较少,于是导致从库回放的并行度并不高,甚至可能一组外面只有一个事务,这样从节点的多线程就根本用不到,能够通过设置上面两个参数,让主节点提早提交。
- binlog_group_commit_sync_delay # 期待提早提交的工夫,binlog 提交后期待一段时间再 fsync。让每个 group 的事务更多,人为进步并行度。
- binlog_group_commit_sync_no_delay_count # 待提交的最大事务数,如果等待时间没到,而事务数达到了,就立刻 fsync。达到冀望的并行度后立刻提交,尽量放大期待提早。
MySQL8.0 基于 writeset 的并行复制
writeset 基于事务后果抵触进行判断事务是否能够进行并行回放的办法,他由
binlog-transaction-dependency-tracking
参数进行管制,默认采纳WRITESET
办法。
要害参数查看
Command-Line Format | –binlog-transaction-dependency-tracking=value |
---|---|
System Variable | binlog_transaction_dependency_tracking |
Scope | Global |
Dynamic | Yes |
SET_VAR Hint Applies | No |
Type | Enumeration |
Default Value | COMMIT_ORDER |
Valid Values | COMMIT_ORDER WRITESET WRITESET_SESSION |
参数配置项阐明
COMMIT_ORDER
# 应用 5.7 Group commit 的形式决定事务依赖。WRITESET
# 应用写汇合的形式决定事务依赖。WRITESET_SESSION
# 应用写汇合,然而同一个 session 中的事务不会有雷同的 last_committed。
writeset 是一个 HASH 类型的数组,外面记录着事务的更新信息,通过
transaction_write_set_extraction
判断以后事务更新的记录与历史事务更新的记录是否存在抵触,判断过后再采取对应解决办法。writeset 贮存的最大存储值由binlog-transaction-dependency-history-size
管制。须要留神的是,当设置成
WRITESET
或WRITESET_SESSION
的时候,事务提交是无序状态的,能够通过设置slave_preserve_commit_order=1
强制按程序提交。
- binlog_transaction_dependency_history_size
设置保留在内存中的行哈希数的下限,用于缓存之前事务批改的行信息。一旦达到这个哈希数,就会革除历史记录。
Command-Line Format | –binlog-transaction-dependency-history-size=# |
---|---|
System Variable | binlog_transaction_dependency_history_size |
Scope | Global |
Dynamic | Yes |
SET_VAR Hint Applies | No |
Type | Integer |
Default Value | 25000 |
Minimum Value | 1 |
Minimum Value | 1000000 |
- transaction_write_set_extraction
该模式反对三种算法,默认采纳 XXHASH64,当从节点配置 writeset 复制的时候,该配置不能配置为 OFF。该参数曾经在 MySQL 8.0.26 中被弃用,后续将会进行删除。
Command-Line Format | –transaction-write-set-extraction[=value] |
---|---|
Deprecated | 8.0.26 |
System Variable | binlog_transaction_dependency_history_size |
Scope | Global, Session |
Dynamic | Yes |
SET_VAR Hint Applies | No |
Type | Enumeration |
Default Value | XXHASH64 |
Valid Values | OFF MURMUR32 XXHASH64 |
数据库配置
slave_parallel_type = LOGICAL_CLOCK
slave_parallel_workers = 8
binlog_transaction_dependency_tracking = WRITESET
slave_preserve_commit_order = 1
援用材料:
- 阿里内核月报:
http://mysql.taobao.org/monthly/2018/06/04/
- 官网文档:
https://dev.mysql.com/doc/refman/8.0/en/replication-options-binary-log.html
Enjoy GreatSQL :)
# 文章举荐:
GreatSQL 季报(2021.12.26)
https://mp.weixin.qq.com/s/FZ…
技术分享 |sysbench 压测工具用法浅析
https://mp.weixin.qq.com/s/m1…
故障剖析 | linux 磁盘 io 利用率高,剖析的正确姿态
https://mp.weixin.qq.com/s/7c…
技术分享 | 闪回在 MySQL 中的实现和改良
https://mp.weixin.qq.com/s/6j…
万答 #20,索引下推如何进行数据过滤
https://mp.weixin.qq.com/s/pt…
对于 GreatSQL
GreatSQL 是由万里数据库保护的 MySQL 分支,专一于晋升 MGR 可靠性及性能,反对 InnoDB 并行查问个性,是实用于金融级利用的 MySQL 分支版本。
Gitee:
https://gitee.com/GreatSQL/Gr…
GitHub:
https://github.com/GreatSQL/G…
Bilibili:
https://space.bilibili.com/13…
微信 &QQ 群:
可搜寻增加 GreatSQL 社区助手微信好友,发送验证信息“加群”退出 GreatSQL/MGR 交换微信群
QQ 群:533341697
微信小助手:wanlidbc
本文由博客一文多发平台 OpenWrite 公布!