Mysql GTID复制+半同步复制+多线程复制

一、GTID复制

GTID的概念是Mysql 5.6版本之后才有的

这是官方文档的介绍,

https://dev.mysql.com/doc/refman/5.7/en/replication-gtids-concepts.html

GTID = source_id:transaction_id

其实GTID是由UUID:序列号 组成,这样每一个事务在集群中都有一个唯一编号,能确定这个事务是由哪个实例执行的。

主主搭方法参考:

https://www.cnblogs.com/nanxiang/p/12902170.html

在搭建完成后,需要对其中的一些参数进行调整,修改my.cnf添加如下内容

gtid_mode=ON
enforce-gtid-consistency=ON
master_info_repository=TABLE 
relay_log_info_repository=TABLE

启动主备数据库,

在服务器A执行, 

mysql> create database ceshi;
Query OK, 1 row affected (0.01 sec)

mysql> show master status\G
*************************** 1. row ***************************
             File: mysql-bin.000014
         Position: 321
     Binlog_Do_DB: 
 Binlog_Ignore_DB: 
Executed_Gtid_Set: 9fef2262-97b1-11ea-92b5-000c29cd3ff3:1    #GTID编号,前边是UIID,后边的是1序列号
1 row in set (0.00 sec)

在服务器B执行

mysql> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.150.101
                  Master_User: replicator
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000014
          Read_Master_Log_Pos: 321
               Relay_Log_File: host102-relay-bin.000005
                Relay_Log_Pos: 534
        Relay_Master_Log_File: mysql-bin.000014
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
            ......
            ...... #内容较多,省略部分内容
           Retrieved_Gtid_Set: 9fef2262-97b1-11ea-92b5-000c29cd3ff3:1    #代表接收到的位点
            Executed_Gtid_Set: 9fef2262-97b1-11ea-92b5-000c29cd3ff3:1    #代表目前执行到哪个位点,如果Retrieved_Gtid_Set和Executed_Gtid_Set不相等,代表有延迟。
 Auto_Position: 0   #等于0代表不自动定位GTID位点,在使用GTID复制模式下,这个值一定要为1
Replicate_Rewrite_DB:
Channel_Name:
Master_TLS_Version:

1 row in set (0.00 sec)

主备库都要执持如下命令:

mysql> stop slave;
Query OK, 0 rows affected (0.01 sec)

mysql> change master to master_auto_position=1;
Query OK, 0 rows affected (0.00 sec)

mysql> start slave;
Query OK, 0 rows affected (0.01 sec)

再次执行show slave status\G

可以看到Auto_Position 值已经为1了。

Executed_Gtid_Set: 9fef2262-97b1-11ea-92b5-000c29cd3ff3:1
                Auto_Position: 1
         Replicate_Rewrite_DB: 
                 Channel_Name: 
           Master_TLS_Version: 
1 row in set (0.00 sec)

 

使用GTID复制会有一些限制,

官方文档,

https://dev.mysql.com/doc/refman/5.7/en/replication-gtids-restrictions.html

CREATE TABLE ... SELECT语句 将不支持。

事务、存储过程、函数、触发器内部,将不能使用CREATE TEMPORARY TABLE and DROP TEMPORARY TABLE 创建临时表。

 sql_slave_skip_counter 跳过事务的方式将不支持。

 

二、半同步复制

 如下图是半步复制流程,

1、主库写入数据,生成binlog日志,

2、发送到备库,

3、本地将binlog刷盘,

4、主库存储引擎层提交事务

5、等待备库返回ACK确认信息,

6、返回给客户端事务成功。

这其中有一些问题,如果因为网络等原因,备库没有收到主库发送的binlog,但在第4步时,存储引擎已经提交了。此时宕机了,就会出现主备数据不一致的问题。

Mysql GTID复制+半同步复制+多线程复制

 

 5.7版本中新加入了无损半同步复制,如下图。

1、主库写入数据,生成binlog日志,

2、发送到备库,

3、本地将binlog刷盘,

4、等待备库返回ACK确认信息,

5、主库存储引擎层提交事务

6、返回给客户端事务成功。

 

与之前的半同步相比,第4步和第5步互换了,要先收到备库的ACK信息,才做存储引擎层提交。

 

 

 

Mysql GTID复制+半同步复制+多线程复制

 

 

搭建步骤:

安装插件,

主库需要安装semisync_master.so

备库需要安装semisync_slave.so

为了满足主备切换后,还能继续使用半同步,主备库都需要同时安装这两个插件。

mysql> INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
Query OK, 0 rows affected (0.01 sec)

mysql> INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
Query OK, 0 rows affected (0.00 sec)

mysql> show plugins;
+----------------------------+----------+--------------------+--------------------+---------+
| Name                       | Status   | Type               | Library            | License |
+----------------------------+----------+--------------------+--------------------+---------+
| binlog                     | ACTIVE   | STORAGE ENGINE     | NULL               | GPL     |
| mysql_native_password      | ACTIVE   | AUTHENTICATION     | NULL               | GPL     |
| sha256_password            | ACTIVE   | AUTHENTICATION     | NULL               | GPL     |
.....
.....中间省略 | rpl_semi_sync_master | ACTIVE | REPLICATION | semisync_master.so | GPL | #可以看到状态是ACTIVE了 | rpl_semi_sync_slave | ACTIVE | REPLICATION | semisync_slave.so | GPL | #可以看到状态是ACTIVE了
+----------------------------+----------+--------------------+--------------------+---------+ 46 rows in set (0.00 sec)

 

查看一些安装插件后新增加的参数

mysql> show global variables like '%rpl_semi%';
+-------------------------------------------+------------+
| Variable_name                             | Value      |
+-------------------------------------------+------------+
| rpl_semi_sync_master_enabled              | OFF        | #半同步复制是否开启
| rpl_semi_sync_master_timeout              | 10000      | #半同步复制超时后转为异步复制时间(单位:毫秒)
| rpl_semi_sync_master_trace_level          | 32         | #用于开启半同步复制模式时的调试级别,默认是32
| rpl_semi_sync_master_wait_for_slave_count | 1          | #最少需要等到几个备库收到binlog后,主库才会提交。
| rpl_semi_sync_master_wait_no_slave        | ON         | #是否允许master每个事务提交后都要等待slave的接收确认信号。默认为on,每一个事务都会等待。如果为off,则slave追赶上后,也不会开启半同步复制模式,需要手工开启。
| rpl_semi_sync_master_wait_point           | AFTER_SYNC | #AFTER_SYNC:备库收到binlog,并返回ACK确认后,主库存储引擎层才做提交操作。 AFTER_COMMIT:主库存储引擎层先提交,再收到备库ACK确认,这个也是旧的半同步复制方案。
| rpl_semi_sync_slave_enabled               | OFF        | #ON表示在slave上已经开启半同步复制模式,由于还没开启半同步复制,所以现在显示为OFF
| rpl_semi_sync_slave_trace_level           | 32         | #用于开启半同步复制模式时的调试级别,默认是32
+-------------------------------------------+------------+
8 rows in set (0.01 sec)

开启半同步复制,主备库都要执行

mysql> SET GLOBAL rpl_semi_sync_master_enabled = 1;
Query OK, 0 rows affected (0.01 sec)

mysql> SET GLOBAL rpl_semi_sync_slave_enabled = 1;
Query OK, 0 rows affected (0.00 sec)

再看下半同步复制状态

mysql> show global variables like '%rpl_semi%';
+-------------------------------------------+------------+
| Variable_name                             | Value      |
+-------------------------------------------+------------+
| rpl_semi_sync_master_enabled              | ON         | #已经为ON
| rpl_semi_sync_master_timeout              | 10000      |
| rpl_semi_sync_master_trace_level          | 32         |
| rpl_semi_sync_master_wait_for_slave_count | 1          |
| rpl_semi_sync_master_wait_no_slave        | ON         |
| rpl_semi_sync_master_wait_point           | AFTER_SYNC |
| rpl_semi_sync_slave_enabled               | ON         | #已经为ON
| rpl_semi_sync_slave_trace_level           | 32         |
+-------------------------------------------+------------+
8 rows in set (0.01 sec)

虽然状态都为ON了,但是需要重启io thread线程才会生效。

mysql> stop slave io_thread;
Query OK, 0 rows affected (0.01 sec)

mysql> start slave io_thread;
Query OK, 0 rows affected (0.00 sec)

 

为了这方便以后每次启动数据库,都运行在同步复制模式下,需要将这些参数加入到my.cnf配置文件中

plugin-load = "rpl_semi_sync_master=semisync_master.so;rpl_semi_sync_slave=semisync_slave.so"
rpl-semi-sync-master-enabled = 1
rpl-semi-sync-slave-enabled = 1

 

验证半同步复制实验:

T1时间点在主库操作:

mysql> create table t1(id int primary key);
Query OK, 0 rows affected (0.01 sec)

mysql> insert into t1 select 1;
Query OK, 1 row affected (0.00 sec)
Records: 1  Duplicates: 0  Warnings: 0

 

T2时间点在备库操作:

mysql> select * from t1;
+----+
| id |
+----+
|  1 |   #可以看到数据已经正常同步过来了
+----+
1 row in set (0.00 sec)

mysql> stop slave io_thread;  #把IO_THREAD线程关掉,停止主备复制
Query OK, 0 rows affected (0.00 sec)

T3时间点在备库操作:

mysql> insert into t1 select 2;
Query OK, 1 row affected (10.01 sec)  #这条插入命令执行了10秒,一直在等备库的ACK,超过10秒就不再等了,从而半同步复制变为了异常复制。
Records: 1  Duplicates: 0  Warnings: 0

mysql> insert into t1 select 3; #因为处于异步复制状态了,不用再等备库的ACK,数据就直接写入了。 Query OK, 1 row affected (0.00 sec) Records: 1 Duplicates: 0 Warnings: 0

 

 介绍一些关于半步复制的状态变量

官方文档连接:

https://dev.mysql.com/doc/refman/5.7/en/replication-options-reference.html

mysql> show global status like '%rpl_semi%';
+--------------------------------------------+-------+
| Variable_name                              | Value |
+--------------------------------------------+-------+
| Rpl_semi_sync_master_clients               | 1     | #有几个备库配置了半同步复制,如上述实验完成后,这里看到的是0,因为备库的io_thread线程停掉了,已经感知不到备库的存在了。
| Rpl_semi_sync_master_net_avg_wait_time     | 0     |
| Rpl_semi_sync_master_net_wait_time         | 0     |
| Rpl_semi_sync_master_net_waits             | 5     |
| Rpl_semi_sync_master_no_times              | 1     |
| Rpl_semi_sync_master_no_tx                 | 2     | #显示备库确认的不成功提交数量
| Rpl_semi_sync_master_status                | ON    | #主库是异步复制模式,还是半同步复制模式
| Rpl_semi_sync_master_timefunc_failures     | 0     |
| Rpl_semi_sync_master_tx_avg_wait_time      | 1685  |
| Rpl_semi_sync_master_tx_wait_time          | 5055  |
| Rpl_semi_sync_master_tx_waits              | 3     |
| Rpl_semi_sync_master_wait_pos_backtraverse | 0     |
| Rpl_semi_sync_master_wait_sessions         | 0     |
| Rpl_semi_sync_master_yes_tx                | 3     | #显示备库确认的成功提交数量
| Rpl_semi_sync_slave_status                 | ON    |
+--------------------------------------------+-------+
15 rows in set (0.00 sec)

 

 

三、多线程复制

默认情况下,MYSQL的复制是单线程的,即备库的io_thread取的binlog日志,并写入到中继日志后,只有sql_thread一个线程去回放日志,

在开启多线程复制后,SQL会变为coordinator线程,同时会有多个worker线程,

coordinator线程主要作用是分发日志给worker线程执行,

如果遇到大事务,coordinator线程便不再发送给worker线程执行,由自己去回放这个大事务。

多线程复制原理基于MYSQL组提交实现,

5.6的多线程程复制是基于库的,也就是不同库中的事务操作,可以并行回放,如果一个库中的多个事务操作,只能顺序回放。

5.7的多线程程复制是基于事务的,一个库中的多个事务,可以实现并行回放。

开启方法:

mysql> show variables like 'slave_parallel%';
+------------------------+----------+
| Variable_name          | Value    |
+------------------------+----------+
| slave_parallel_type    | DATABASE |   #默认是基于库的,需要修改参数为LOGICAL_CLOCK,修改这个参数,要先停掉主从复制
| slave_parallel_workers | 0        |
+------------------------+----------+
2 rows in set (0.01 sec)

mysql> stop slave;
Query OK, 0 rows affected (0.01 sec)

mysql> set global slave_parallel_type='LOGICAL_CLOCK';
Query OK, 0 rows affected (0.00 sec)

mysql> set global slave_parallel_workers=4; #设置worker线程数据,配置较低选择4或8,配置较高可以配置为16
Query OK, 0 rows affected (0.00 sec)

mysql> start slave;
Query OK, 0 rows affected (0.01 sec)

 

同时也要修改my.cnf配置文件,重启数据库后也能生效:

slave_parallel_workers=4
slave_parallel_type='LOGICAL_CLOCK'

 

可以看到已经有4个worker线程了

mysql> show processlist;
+----+-------------+-----------+------+---------+------+--------------------------------------------------------+------------------+
| Id | User        | Host      | db   | Command | Time | State                                                  | Info             |
+----+-------------+-----------+------+---------+------+--------------------------------------------------------+------------------+
|  1 | system user |           | NULL | Connect |   11 | Slave has read all relay log; waiting for more updates | NULL             |
|  2 | system user |           | NULL | Connect |   11 | Waiting for master to send event                       | NULL             |
|  4 | system user |           | NULL | Connect |   11 | Waiting for an event from Coordinator                  | NULL             |
|  5 | system user |           | NULL | Connect |   11 | Waiting for an event from Coordinator                  | NULL             |
|  6 | system user |           | NULL | Connect |   11 | Waiting for an event from Coordinator                  | NULL             |
|  7 | system user |           | NULL | Connect |   11 | Waiting for an event from Coordinator                  | NULL             |
|  8 | root        | localhost | NULL | Query   |    0 | starting                                               | show processlist |
+----+-------------+-----------+------+---------+------+--------------------------------------------------------+------------------+
7 rows in set (0.00 sec)

 

上一篇:Laravel 查询 多个or或者and条件


下一篇:laravel 框架登录 参考