MariaDB Parallel Replication 并行复制

官方文档: https://mariadb.com/kb/en/mariadb/parallel-replication

从10.0.5版本开始,MariaDB开始支持并行复制

MariaDB10.0的从服务器能并行的执行查询和复制操作,这篇文章将会解释是如何实现的和你可以做的调优。

注意:主从服务器上的 MariaDB 的版本必须是10.0.5和10.0.5的以后的版本,才能启用并行复制

Parallel replication overview -- 并行复制概述

MariaDB 的复制通过三步完成:

1.从服务的IO线程去主库上读取变更事件,并把读取的事件顺序放到relay log中

2.从服务器的SQL线程一次读取relay log中的一个事件

3.SQL线程依次应用relay log中的事件

MariaDB 10之前的版本中,第三步是通过SQL线程来执行的,这意味着,一次只能执行一个事件,复制本质上是单线程的。

MariaDB 10之后的版本中,第三步可以通过一组相互独立的复制线程,因为可以一次并行复制多个事件,提升了复制性能。

How to enable parallel slave -- 如何开启并行复制

在 my.cnf 指定 slave-parallel-threads = n 作为参数传递给MySQL.

并行复制也可以用于多源连接设置 "@@connection_name.slave-parallel-mode" 设置为 none, 即 set @@connection_name.slave-parallel-mode = none

slave_parallel_threads 的值决定了池中会有多少个工作线程会被创建用来在从服务器上执行并行复制事件

如果值为0,默认采用旧的复制方式(即slave的SQL线程来重放event事件)

通常来讲,如果值为非0,应该设置为多源主服务器链接数的至少两倍。一个连接用一个工作线程的意义不大,因为这不但会增加内部线程通讯(即SQL线程和工作线程之间的通讯)的负担,而且一个连接使用一个工作线程的时候,事件不能被并行复制。

slave_parallel_threads 的值可进行动态调整,即可在不重启MySQL的情况下,进行更改,但是更改的时候,所有的从库连接都要被停止。

What can be run in parallel  -- 如何运行并行复制

并行复制的方式有哪些?

in-order 有序 和 out-of-order 无序两种方式

有序方式

并行执行事务,但是对commit顺序进行排序,以确保从库上事务提交和主库上事务提交顺序一致。只有那些被自动确认为不会引起冲突的事务才会被并行执行,也就是说,并行复制对应用来说,是完全透明的。

无序方式

无序意味着在从库上执行和提交事务的顺序跟主库可能不一致,也就是说,应用必须要具备容忍主从服务器上数据更新顺序不一致的问题,同时这种方式要求应用来确保事务之间的没有冲突。无序方式只在GTID模式和应用明确指定使用无序的时候才会被使用, 复制域属于gtid的一部分。

Conservative mode of in-order parallel -- 乐观并行复制模式(optimistic)

Optimistic模式,从MariaDB 10.1.3版本开始支持。

这种模式提供了大量的并行应用slave,同时从应用程序的角度来看,仍然保留精确的事务语义。

开启使用配置选项 --slave-parallel-mode=optimistic.

任何事务DML(插入/更新/删除)可以并行运行,达到限制@@slave_domain_parallel_threads。这可能在slave导致冲突,如果两个交易试图修改同一行,检测到任何这样的冲突,并且两个事务的后者被回滚,允许前者继续, 一旦前者已经完成,后者的事务重新尝试。

Optimistic模式适用于这种方式,因为服务器会发生一些冲突乐观的假定,这额外的工作花了回滚后重新事务冲突时从运行大部分交易获得合理的并行。

有一些启发,试图避免不必要的冲突,如果在master上一个事务执行了一个行锁等待。它不会再并行运行slave,

事务也可以明确在master上标识为潜在的冲突,通过设置变量@@skip_parallel_replication。这种启发式可能在以后加入MariaDB版本(现在还不支持)

这是接下来的选项--slave-parallel-mode 叫 侵略性"aggressive"模式。当这些启发式呗禁用,允许更多的交易将被应用在并行。

非事务DML和DDL不安全的乐观应用并行,因为它不能再冲突的情况下,回滚。因此,在乐观的模式下,非事务性的(如MyISAM)更新不适用于并行或者早期的事件。(不过,可能适用于并联一个MyISAM更新后会更新),DDL语句不适用于任何其他事务,或早或晚。

不同的事务类型可以在mysqlbinlog输出确定,例如:

#150324 13:06:26 server id 1  end_log_pos 6881 GTID 0-1-42 ddl

...

#150324 13:06:26 server id 1  end_log_pos 7816 GTID 0-1-47

...

#150324 13:06:26 server id 1  end_log_pos 8177  GTID 0-1-49 trans

/*!100101 SET @@session.skip_parallel_replication=1*//*!*/;

...

#150324 13:06:26 server id 1  end_log_pos 9836 GTID 0-1-59 trans waited

gtid 0-1-42标明DDL。gtid 0-1-47被标记为非事务DML。而gtid 0-1-49是事务性的DML("trans" 关键字),另外,gtid 0-1-49在master上运行@@ skip_parallel_replication,gtid 0-1-59是事务型的,在master上有一排等待DML锁。("waited" 关键字)。

Conservative mode of in-order parallel -- 保守并行复制(conservative)模式

默认是conservative模式,在10.0版本中唯一可用的模式,可以使用 --slave-parallel-mode=conservative 开启。

在conservative模式中,并行复制在master上使用"组提交“,以发现潜在的并行应用事件的slave,

在mater上如果两个事物提交在一组,他们都写进同一个commit id,此类事件的binlog一定不会互相冲突,他们可以计划安排由复制到运行在不同的线程中。

两个在主上单独提交的事务可能会发生冲突(如,修改同一个表的一行)。因此,应用第二个事务的worker不会立即开始。

但是等到第一个事务开始提交步骤之后,在这一点上,启动第二个事务是安全的,因为它不能再扰乱第一个的执行。

这是mysqlbinlog输出的一个例子,显示gtid events都标有commit id,gtid 0-1-47 没有提交ID,不能并行运行,

gtid 0-1-48和0-1-49有相同的commit id 630,可以在另一个slave上并行复制。

binlog信息如下:

#150324 12:54:24 server id 1  end_log_pos 20052 GTID 0-1-47 trans

...

#150324 12:54:24 server id 1  end_log_pos 20212 GTID 0-1-48 cid=630 trans

...

#150324 12:54:24 server id 1  end_log_pos 20372 GTID 0-1-49 cid=630 trans

在任何一种情况下,当两个事务到达低级别提交的点,并确定提交顺序时,这两个提交以相同的顺序发生在mater上,这样操作对应用程序是透明的。

如果在一个组提交中提交了更多的事务,则可以高度地增加对slave的并行复制的机会。

这个可以调整使用binlog_commit_wait_count和binlog_commit_wait_usec变量,例如,如果应用程序在master可以容忍额外延迟50毫秒,你可以设置binlog_commit_wait_usec = 50000和binlog_commit_wait_count = 20,在一个可用的时间,并行复制可获得高达20的事务处理。

不过小心不要设置binlog_commit_wait_usec太高,因为这可能导致应用程序会放缓,运行大量的串行小事务一个接一个的。

请注意:在master上即使没有组提交的并行性,仍然有个机会,提升并行速度。

由于不同事务的实际提交步骤可以运行。在slave上特别有效,binlog开启(log_slave_updates=1)

甚至如果slave配置崩溃修复安全(sync_binlog=1 and innodb_flush_log_at_trx_commit=1),这种组提交可能在slave上

在--slave-parallel-mode=minimal模式下,仅仅事务提交步骤被并行应用。所有其他事务复制都是连续发生的。

Out-of-order parallel -- 无序并行复制

无序并行复制只使用在GTID模式下,当使用不同的复制域GTID时,复制域是有DBA/应用程序中使用的变量gtid_domain_id.

在并行复制中有两个事务gtids,不同domain_id定于不同的线程,并允许执行完全独立于此,它是应用程序的责任,只为那些真正独立的交易设置不同的domain_ids,

并保证不会相互冲突,应用程序还必须正常工作,即使事务中有不同的domain_id,被视为不同的顺序呢,在slave和master之间,或者在不同的slave中。

由于应用程序可以显式地提供更多并行运行事务的机会。而不是服务器可以自动确定的,出于事务并行复制的顺序并行复制可能自动自己确定自己

一个简单但有效的用法是运行单独的复制域中的长时间运行的语句,如“更改表”。这允许复制其他事务继续进行不间断:

SET SESSION gtid_domain_id=1

ALTER TABLE t ADD INDEX myidx(b)

SET SESSION gtid_domain_id=0

通常,一个长时间运行的ALTER TABLE语句或者 其他查询,将会停止所有后面的事务。会引发slave落后于master至少需要很长的时间去执行这个运行时间很长的查询。

通过无序并行复制,设置复制domain id。是可以避免的。当运行ALTER TABLE时,DBA/应用程序必须确保没有冲突的事务将被复制。

出于无序并行复制的另一个常见的条件,是于多源复制有关的。假设我们有两个不同的master M1 M2,我们利用多源复制S1作为一个M1和M2的slave,S1将收到从M2事件并行M1接收事件。

如果我们现在有三分之一级的奴隶,从S1 S2复制master,我们希望S2也能够应用事件起源于M1与M2平行事件起源于。这可以从顺序并行复制来实现,通过设置在M1和M2 gtid_domain_id不同。

请注意,没有什么特殊限制,可以使用无序的并行复制,这样的操作可以在同一个database/schema,甚至在同一个table中,唯一的限制是,操作必须不冲突,这是他们必须能够以任何顺序应用,并最终获得相同的结果。

当使用了无序并行复制时,

当前slave position就是 master 位置

在master binlog在任何一个时间,成为多维 - 每个复制域可以达到一个不同的点,

当前的position可以在gtid_slave_pos变量看到。当slave被停止、重启、或者切换复制从不同master 使用CHANGE MASTER时,MariaDB自动处理重启每个复制域在binlog适当点。

当--slave-parallel-mode=minimal(或none)模式,无序并行复制是关闭的。

Checking worker thread status in SHOW PROCESSLIST -- 检查显示列表的线程状态

在show processlist中,工作线程将会列出"system user",他们的状态将显示他们目前正在进行的查询,或者它可以显示其中一个:

"Waiting for work from main SQL threads". "等待工作从主要的SQL线程"。

这意味着工作线程空闲,没有工作可用于它的时刻。

"Waiting for prior transaction to start commit before starting next transaction". "等待之前的交易开始下一次交易开始之前提交"。

这意味着,前一批提交的事务在主必须完成第一个。这个工作线程在等待它发生之前,它可以开始工作在下面的一批。

This worker thread is waiting for that to happen before it can start working on the following batch.

"Waiting for prior transaction to commit". ”等待优先交易提交“。

这意味着事务已被工作线程执行了,为了确保订单提交,工作线程等待提交,知道上一次事务准备在它之前提交为止。

Expected performance gain -- 性能预期测试的文章

这里有一篇关于使用并行复制时,改进后高达10倍的性能文章

文章地址: http://kristiannielsen.livejournal.com/18435.html。

slave-parallel-max-queued配置参数:

变量slave_parallel_max_queued是唯一有意义的,前提并行复制技术被使用(slave_parallel_threads参数大于0时),当并行复制被使用时, SQL线程会预读relay-log中的event,队列时间放在内存中,在并行复制中,同时寻找并行执行事件的机会。@@slave_parallel_max_queued变量设置为SQL 线程将在预读多少内存限制的日志,寻找这样的机会。每个线程是有限制的,因此,这次预读的值是设置@@slave_parallel_threads变量值得来的

如果这个值设置的太高,并且slave落后于master落得太远(如千兆字节的binlog),然后SQL线程可以快速读,填补大量内存的binlog事件比工作线程消耗的更快

另一方面,如果值定的太低,SQL线程可能没有足够的空间来保持足够的事件队列忙的线程,这可能降低性能。

注意,@@slave_parallel_max_queued不是硬性限制,因为binlog事件当前执行总是需要保存在内存中,

例如,每个工作者线程至少有两个事件总是可以在内存中排队,不管slave_parallel_threads是多

通常,slave_parallel_threads应该设置的足够大,SQL线程利用所有可能的并行性可以预读的足够远的binlog,在正常操作中,slave将不希望落后太远,因此不会将大量数据队列有必要的放在内存中的。所以slave_parallel_threads可能设置的相当高(如几百KB)不限制吞吐量。它应该被设置的足够低,slave_parallel_threads * slave_parallel_max_queued 不会造成服务器内存不足。

slave_domain_parallel_threads配置参数:

在所有多源主连接中共享复制工作线程池,在所有可以在并行使用顺序复制的复制域中。

如果一个主连接或者一个复制域 当前正在执行处理一个长时间的查询,可能它将分配在池中的所有工作线程,只能等待让他们长时间运行的查询完成。

拖延任何master主库连接或者复制域,这将不得不等待复制域工作线程变得空闲。

可以通过slave_domain_parallel_threads变量设置的值避免低于slave_parallel_threads设置的值,

当设置不等于0时,一个主连接中的每个复制域都可以保留至多一个时间段的多个线程,

其余的,达到slave_parallel_threads参数的值,在并行复制中无其他主连接或者复制域去使用。

slave_domain_parallel_threads变量是可以动态修改的,可以在不重启服务的情况下更改。所有的slave必须停止掉更改。

时间: 2024-10-06 00:40:13

MariaDB Parallel Replication 并行复制的相关文章

MariaDB 10之并行复制--延迟测试结果

测试参数: sysbench  --test=/root/sysbench0.5/sysbench/tests/db/insert.lua  --mysql-table-engine=innodb --oltp-table-size=1000000  --max-requests=0 --max-time=300 --num-threads=16  --oltp-tables-count=10 --report-interval=10  --mysql-host=10.8.8.100 --mys

mariadb multi-source replication(mariadb多主复制)

下文一起来看看mariadb multi-source replication(mariadb多主复制)例子,希望对各位有帮助. mariadb multi-source replication(mariadb多主复制)在mariadb-10.0里面加入了多主复制功能. 修改过的语法:针对每个复制线程会有一个对应的connection_name,而connection_name是default_master_connection变量的值,如果你要操作对应的复制线程,需要将这个变量设置为对应的复制

mariadb 10 多源复制(Multi-source replication) 业务使用场景分析,及使用方法

mariadb 10 多源复制(Multi-source replication) 业务使用场景分析,及使用方法 官方mysql一个slave只能对应一个master,mariadb 10开始支持多源复制,一个slave可以有多个master,分别从各自的master复制不同的DB. 这个特性可以用在OLAP环境中,传统电商DB都是拆了再拆,分库分表,sharding,而OLAP环境或者大数据平台环境,通常需要各种数据的聚合,多个平台多个DB数据的复合查询,而这些数据分散在各个库中,怎么办了,当

MySQL 5.7 并行复制实现原理与调优

MySQL 5.7并行复制时代 众所周知,MySQL的复制延迟是一直被诟病的问题之一,然而在Inside君之前的两篇博客中(1,2)中都已经提到了MySQL 5.7版本已经支持“真正”的并行复制功能,官方称为为enhanced multi-threaded slave(简称MTS),因此复制延迟问题已经得到了极大的改进,甚至在Inside君所在的网易电商应用中已经完全消除了之前延迟长达几小时的问题.然而,Inside君发现还是有很部分小伙伴不了解这个足以载入史册的“伟大”的特性,故作分享.总之,

InnoSQL/MySQL并行复制的实现与配置

InnoSQL/MySQL并行复制的实现与配置 http://www.innomysql.net/article/6276.html 并行复制之前的解决方案 InnoSQL在5.5.30-v4版本中支持了从机并行复制的功能.总所周知,MySQL数据库slave服务器延迟的现象是非常普遍的,这导致了虽然对比Oracle.Microsoft SQL Server,MySQL复制允许从机进行SELECT操作,但是在实际线上环境下,由于从机延迟的关系,很难将读取操作转向到从机.这就导致了有了以下一些潜规

利用MariaDB Galera Cluster实现mariadb的多主复制

利用MariaDB Galera Cluster实现mariadb的多主复制 时间:2014年01月08日 | 分类:MariaDB | 评论:0 条 | 浏览:870 次 一.MariaDB Galera Cluster概要: 1.简述: MariaDB Galera Cluster 是一套在mysql innodb存储引擎上面实现multi-master及数据实时同步的系统架构,业务层面无需做读写分离工作,数据库读写压力都能按照既定的规则分发到 各个节点上去.在数据方面完全兼容 MariaD

mysql 并行复制

并行复制,主要是解决sql_thread在高并发环境下,存在性能瓶颈.mysql5.7并行复制的思想简单易懂,一个组提交的事务都是可以并行回放,因为这些事务都已进入到事务的prepare阶段,则说明事务之间没有任何冲突(否则就不可能提交). 为了兼容MySQL 5.6基于库的并行复制,5.7引入了新的变量slave-parallel-type,其可以配置的值有: (1)DATABASE:默认值,基于库的并行复制方式 (2)LOGICAL_CLOCK:基于组提交的并行复制方式 操作步骤: 数据库版

5.7 并行复制配置 基于GTID 搭建中从 基于GTID的备份与恢复,同步中断处理

5.7 并行复制配置 基于GTID 搭建中从 基于GTID的备份与恢复,同步中断处理 这个文章包含三个部分 1:gtid的多线程复制2:同步中断处理3:GTID的备份与恢复 下面文字相关的东西 大部分都比较重要,可以看一下master: 192.168.17.21slave: 192.168.17.22salve: 192.168.17.23 分别在这三个机器上面安装 编译安装mysql 5.7 不会安装的话 这有安装脚本 https://www.cnblogs.com/noel/p/10314

C#5.0之后推荐使用TPL(Task Parallel Libray 任务并行库) 和PLINQ(Parallel LINQ, 并行Linq). 其次是TAP(Task-based Asynchronous Pattern, 基于任务的异步模式)

学习书籍: <C#本质论> 1--C#5.0之后推荐使用TPL(Task Parallel Libray 任务并行库) 和PLINQ(Parallel LINQ, 并行Linq). 其次是TAP(Task-based Asynchronous Pattern, 基于任务的异步模式). --用AggregateException处理Task上的未处理异常. --取消任务. CancellationToken --async修饰方法, 返回Task. task.wait(100)可以阻塞现场. a