Maison > Article > base de données > Comment implémenter la réplication parallèle dans la réplication MySQL
Comme nous le savons tous, avant la version 5.6 de MySQL, il y avait deux threads sur le nœud esclave de la réplication maître-esclave, à savoir le thread d'E/S et le thread SQL.
Le thread d'E/S est chargé de recevoir les événements du journal binaire et de les écrire dans le journal de relais.
Le thread SQL lit le journal du relais et le relit dans la base de données.
La méthode ci-dessus entraînera parfois des retards, alors quelles sont les situations qui peuvent entraîner des retards entre les nœuds maître et esclave
1. La base de données principale exécute des transactions volumineuses (telles que des modifications importantes de la structure des tables) ? .
2. Modifications à grande échelle de la base de données principale (telles que des opérations d'insertion, de mise à jour et de suppression à grande échelle).
3. En mode de synchronisation ROW, la table principale de la base de données n'a pas de clé primaire fréquemment mise à jour.
4. La configuration des paramètres de la base de données est déraisonnable et il existe un goulot d'étranglement dans les performances du nœud esclave (par exemple : le paramètre du journal des transactions du nœud esclave est trop petit, ce qui entraîne un vidage fréquent du disque).
5. L'environnement réseau est instable et il y a des retards et des reconnexions dans la lecture du journal binaire à partir du thread IO du nœud.
6. La configuration matérielle maître-esclave est différente et l'utilisation des ressources matérielles du nœud esclave atteint la limite supérieure. (Par exemple : disque SSD du nœud maître, disque SAS du nœud esclave)
Vous pouvez classer grossièrement les raisons de retard ci-dessus.
1. Problèmes matériels (y compris les E/S du disque, les E/S du réseau, etc.)
2.
3. Problèmes de conception de base de données.
4. La base de données principale change en grande quantité et le traitement SQL monothread du nœud esclave n'est pas assez rapide.
Après avoir analysé les raisons ci-dessus, on peut voir que afin de réduire le délai maître-esclave, en plus d'améliorer les conditions matérielles, le DBA doit également prêter attention à la conception et à la configuration de la base de données. Enfin, il est nécessaire d'améliorer les capacités de traitement simultané des nœuds esclaves, le passage d'une lecture monothread à une lecture parallèle multithread est une meilleure méthode. Le point clé est de savoir comment résoudre le problème des conflits de données et de la confirmation. de points de localisation de récupération de pannes dans le cadre d'une récupération multithread.
Lorsqu'il y a plusieurs bases de données dans l'instance, plusieurs threads peuvent être démarrés et chaque thread correspond à une base de données. Dans ce mode, le nœud esclave démarrera plusieurs threads. Les threads sont divisés en deux catégories :
Coordinateur
etWorkThread
.Coordinator
和WorkThread
。
线程分工执行逻辑
Coordinator
线程负责判断事务是否可以并行执行,如果可以并行就把事务分发给WorkThread
线程执行,如果判断不能执行,如DDL
,跨库操作
等,就等待所有的worker线程执行完成之后,再由Coordinator
执行。
关键配置信息
slave-parallel-type=DATABASE
方案不足点
这种并行复制的模式,只有在实例中有多个DB且DB的事务都相对繁忙的情况下才会有较高的并行度,但是日常维护中其实单个实例的的事务处理相对集中在一个DB上。大多数延迟情况都基于热点表的出现而观察得出。如果能够提供基于表的并行度是一个很好方法。
简单来说就是在双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
Coordinateur
est chargé de déterminer si la transaction peut être exécutée en parallèle. Si elle peut être exécutée en parallèle, la transaction sera distribuée. au thread WorkThread
pour exécution. S'il est jugé qu'il ne peut pas être exécuté, comme DDL
, opération entre bibliothèques
, etc. , attendez que tous les threads de travail terminent l'exécution, puis exécutez-le par Coordinateur
. Informations de configuration clés
🎜🎜[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🎜🎜🎜Défauts du schéma🎜🎜🎜🎜🎜Ce mode de réplication parallèle n'est disponible que lorsqu'il y a plusieurs bases de données dans l'instance et que les transactions des bases de données sont relativement occupées. Degré élevé de parallélisme, mais dans la maintenance quotidienne, le traitement des transactions d'une seule instance est relativement concentré sur une seule base de données. La plupart des retards sont observés en fonction de la présence de tables de points chauds. Ce serait une bonne idée de fournir un parallélisme basé sur des tables. 🎜🎜
Laoye Teahouse
sur la soumission de groupe https://mp.weixin.qq.com/s/rcPkrutiLc93aTblEZ7sFg
🎜🎜🎜Un groupe des transactions sont soumises en même temps. Cela signifie qu'il n'y a pas de conflit dans les transactions au sein du groupe, donc les transactions du groupe peuvent être exécutées simultanément sur le nœud esclave. Le problème est de savoir comment distinguer si les transactions sont dans le même groupe. groupe, donc deux nouvelles informations de paramètres apparaissent dans le binlog last_commit
et sequence_number
🎜🎜🎜🎜Comment juger si une transaction est dans un groupe ?🎜🎜🎜🎜🎜Quand vous analysez le binlog, vous pouvez constater qu'il y a plus de last_commit
et de sequence_number
Deux informations sur les paramètres, parmi lesquelles last_commit
est dupliqué. 🎜🎜🎜🎜🎜sequence_number
# Cette valeur fait référence au numéro de séquence de soumission de transaction, qui augmente de façon monotone. 🎜🎜🎜🎜last_commit
# Cette valeur a deux significations. 1. La même valeur signifie que ces transactions sont dans le même groupe, 2. Cette valeur représente également le nombre maximum du groupe de transactions précédent. 🎜🎜🎜slave-parallel-type=LOGICAL_CLOCK🎜🎜🎜Configuration de la base de données🎜🎜🎜
slave_parallel_type = LOGICAL_CLOCK slave_parallel_workers = 8 binlog_transaction_dependency_tracking = WRITESET slave_preserve_commit_order = 1🎜🎜🎜Inadéquation du plan🎜
基于组提交的同步有个不足点,就是当主节点的事务繁忙度较低的时候,导致时间段内组提交fsync刷盘的事务量较少,于是导致从库回放的并行度并不高,甚至可能一组里面只有一个事务,这样从节点的多线程就基本用不到,可以通过设置下面两个参数,让主节点延迟提交。
binlog_group_commit_sync_delay # 等待延迟提交的时间,binlog提交后等待一段时间再 fsync。让每个 group 的事务更多,人为提高并行度。
binlog_group_commit_sync_no_delay_count # 待提交的最大事务数,如果等待时间没到,而事务数达到了,就立即 fsync。达到期望的并行度后立即提交,尽量缩小等待延迟。
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
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!