【原理】MySQL主从复制之增强半同步(无损复制)、延迟复制和并行复制
简介
MySQL主从复制过程:
主从复制方式
MySQL有四种同步方式:
1、异步复制(Async Replication)
2、同步复制(sync Replication)
3、半同步复制(Async Replication)
4、增强半同步复制(lossless Semi-Sync Replication)、无损复制
1、异步复制(Async Replication)
主库将更新写入Binlog日志文件后,不需要等待数据更新是否已经复制到从库中,就可以继续处理更多的请求。Master将事件写入binlog,但并不知道Slave是否或何时已经接收且已处理。在异步复制的机制的情况下,如果Master宕机,事务在Master上已提交,但很可能这些事务没有传到任何的Slave上。假设有Master->Salve故障转移的机制,此时Slave也可能会丢失事务。MySQL复制默认是异步复制,异步复制提供了最佳性能。
2、同步复制(Sync Replication)
主库将更新写入Binlog日志文件后,需要等待数据更新已经复制到从库中,并且已经在从库执行成功,然后才能返回继续处理其它的请求。同步复制提供了最佳安全性,保证数据安全,数据不会丢失,但对性能有一定的影响。
3、半同步复制(Semi-Sync Replication)
主库提交更新写入二进制日志文件后,等待数据更新写入了从服务器中继日志中,然后才能再继续处理其它请求。该功能确保至少有1个从库接收完主库传递过来的binlog内容已经写入到自己的relay log里面了,才会通知主库上面的等待线程,该操作完毕。
半同步复制,是最佳安全性与最佳性能之间的一个折中。
MySQL 5.5版本之后引入了半同步复制功能,主从服务器必须安装半同步复制插件,才能开启该复制功能。如果等待超时,超过rpl_semi_sync_master_timeout参数设置时间(默认值为10000,表示10秒),则关闭半同步复制,并自动转换为异步复制模式。当master dump线程发送完一个事务的所有事件之后,如果在rpl_semi_sync_master_timeout内,收到了从库的响应,则主从又重新恢复为增强半同步复制。
ACK (Acknowledge character)即是确认字符。
4、增强半同步复制(lossless Semi-Sync Replication、无损复制)
增强半同步是在MySQL 5.7引入,其实半同步可以看成是一个过渡功能,因为默认的配置就是增强半同步,所以,大家一般说的半同步复制其实就是增强的半同步复制,也就是无损复制。
增强半同步和半同步不同的是,等待ACK时间不同
rpl_semi_sync_master_wait_point = AFTER_SYNC(默认)
半同步的问题是因为等待ACK的点是Commit之后,此时Master已经完成数据变更,用户已经可以看到最新数据,当Binlog还未同步到Slave时,发生主从切换,那么此时从库是没有这个最新数据的,用户看到的是老数据。
增强半同步将等待ACK的点放在提交Commit之前,此时数据还未被提交,外界看不到数据变更,此时如果发送主从切换,新库依然还是老数据,不存在数据不一致的问题。
图示如下:
异步复制示例
MySQL主从复制之1主2从异步复制搭建及同步测试参考:https://www.xmmup.com/dbbao64mysqlzhucongzhi1zhu2congyibufuzhidajianjitongbuceshi.html
如何配置半同步复制
11.分别在主从安装插件
2 主: INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
3 从: INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
42.主服务器开启半同步
5 set global rpl_semi_sync_master_enabled=on;
63.从服务器开启半同步
7 set global rpl_semi_sync_slave_enabled=on;
8
94.配置主从同步(GTID模式示例)
10server-id=1 (从为2,保证唯一性)
11log-bin=master-bin
12log-bin-index=master-bin.index
13binlog-format=ROW
14gtid-mode=on
15enforce-gtid-consistency=true
延迟从库
延迟从库:从库落后于主库一段时间。
SQL线程延时:数据已经写入relaylog中了,只是让SQL线程”慢点”运行
MySQL延迟复制的好处主要有几点:
1.误删除时,能更快恢复数据。有时候手抖了,把线上数据给误删除了,或者误删除库、表、其他对象,或不加WHERE条件的更新、删除,都可以让延迟从库在误操作前的时间点停下,然后进行恢复。
2.把延迟从库作为专用的备份节点。虽然有一定的延迟,但并不影响利用该节点作为备份角色,也不影响生产节点数据库。
3.还可以把延迟从库当做一些问题、案例研究的对象。个别时候,可能有些Binlog Event在普通从库上会有问题(例如:早期版本中无主键会导致从库更新非常慢的经典问题),这时就有时间在延迟从库上慢慢琢磨研究了。
一般企业建议3-6小时,具体看公司运维人员对于故障的反应时间。
启用延迟从库的方法也挺简单的:
1#直接用CHANGE MASTER TO设置,后面的N单位是秒数:
2STOP SLAVE SQL_THREAD;
3CHANGE MASTER TO MASTER_DELAY = N;
4START SLAVE SQL_THREAD;
5查询:
6show slave status\G
7SQL_Delay: 0
并行复制
MySQL 5.6提供了并行复制,但是这种并行只是基于database的(slave-parallel-type=DATABASE)。如果用户的MySQL数据库实例中存在多个database,对于从库复制的速度的确可以有比较大的帮助。如果是基于单个database的复制依然无法做到真正的并行回放,这个阶段很多DBA将数据库进行垂直拆分,将一个database拆分成几个database,通过设置slave_parallel_workers=n,可以进行database级别的并行复制,但对于热点业务复制延迟依然无法解决。参数slave_parallel_workers默认值为0,表示禁用并行。
到了MySQL 5.7,才实现了真正的并行复制(slave-parallel-type=LOGICAL_CLOCK),复制效率提升很多。MySQL 5.7的并行复制,multi-threaded slave即MTS,期望最大化还原主库的并行度,实现方式是在binlog event中增加必要的信息,以便slave节点根据这些信息实现并行复制。
要开启 MySQL 5.7 并行复制需要以下2步:
1、首先在主库设置 binlog_group_commit_sync_delay 的值大于0 。
1set global binlog_group_commit_sync_delay=10;
2set global binlog_group_commit_sync_no_delay_count=10;
binlog_group_commit_sync_delay 全局动态变量,单位微妙,默认0,范围:0~1000000(1秒)。
表示 binlog 提交后等待延迟多少时间再同步到磁盘,默认0 ,不延迟。当设置为 0 以上的时候,就允许多个事务的日志同时一起提交,也就是我们说的组提交。组提交是并行复制的基础,我们设置这个值的大于 0 就代表打开了组提交的功能。
binlog_group_commit_sync_no_delay_count 全局动态变量,单位个数,默认0,范围:0~1000000。
表示等待延迟提交的最大事务数,如果上面参数的时间没到,但事务数到了,则直接同步到磁盘。若 binlog_group_commit_sync_delay 没有开启,则该参数也不会开启。
2、其次要在 Slave 主机上设置如下几个参数:
1set global slave-parallel-type=LOGICAL_CLOCK;
2set global slave-parallel-workers=16;
一、1主2从之增强半同步复制(无损复制)示例
半同步复制比异步复制多了如下步骤:
1-- 1.分别在主从安装插件
2 主: INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
3 从: INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
4-- 2.主服务器开启半同步
5 set global rpl_semi_sync_master_enabled=on;
6-- 3.从服务器开启半同步
7 set global rpl_semi_sync_slave_enabled=on;
1、MySQL环境初始化
1-- 设置主从的网络环境
2docker pull mysql:5.7.36
3docker network create --subnet=172.72.0.0/24 mysqln0
4
5
6-- 删除之前的容器
7docker rm -f MSS57M33650 MSS57S33651 MSS57S33652
8
9-- 创建参数文件路径
10mkdir -p /lhrmysqltest3/master/conf.d
11mkdir -p /lhrmysqltest3/slave1/conf.d
12mkdir -p /lhrmysqltest3/slave2/conf.d
13
14
15-- 申请主库环境
16docker run -d --name MSS57M33650 \
17 -h master -p 33650:3306 --net=mysqln0 --ip 172.72.0.50 \
18 -v /lhrmysqltest3/master/conf.d:/etc/mysql/conf.d \
19 -e MYSQL_ROOT_PASSWORD=lhr \
20 mysql:5.7.36
21
22-- 申请从库1环境
23docker run -d --name MSS57S33651 \
24 -h slave1 -p 33651:3306 --net=mysqln0 --ip 172.72.0.51 \
25 -v /lhrmysqltest3/slave1/conf.d:/etc/mysql/conf.d \
26 -e MYSQL_ROOT_PASSWORD=lhr \
27 mysql:5.7.36
28
29-- 申请从库2环境
30docker run -d --name MSS57S33652 \
31 -h slave2 -p 33652:3306 --net=mysqln0 --ip 172.72.0.52 \
32 -v /lhrmysqltest3/slave2/conf.d:/etc/mysql/conf.d \
33 -e MYSQL_ROOT_PASSWORD=lhr \
34 mysql:5.7.36
35
36
37-- 配置主库参数
38cat > /lhrmysqltest3/master/conf.d/my.cnf <<"EOF"
39[mysqld]
40port=3306
41character_set_server=utf8mb4
42secure_file_priv=
43server-id = 5733650
44log-bin =
45binlog_format=row
46skip-name-resolve
47gtid-mode=ON
48enforce-gtid-consistency=on
49report_host=172.72.0.50
50default-time-zone = '+8:00'
51log_timestamps = SYSTEM
52log_slave_updates = 1
53master_info_repository='table'
54relay_log_info_repository='table'
55relay_log_recovery=1
56
57EOF
58
59-- 配置从库1参数
60cat > /lhrmysqltest3/slave1/conf.d/my.cnf <<"EOF"
61[mysqld]
62port=3306
63character_set_server=utf8mb4
64secure_file_priv=
65server-id = 5733651
66log-bin =
67binlog_format=row
68gtid-mode=ON
69enforce-gtid-consistency=ON
70skip_name_resolve
71report_host=172.72.0.51
72default-time-zone = '+8:00'
73log_timestamps = SYSTEM
74log_slave_updates = 1
75master_info_repository='table'
76relay_log_info_repository='table'
77relay_log_recovery=1
78
79EOF
80
81
82-- 配置从库2参数
83cat > /lhrmysqltest3/slave2/conf.d/my.cnf <<"EOF"
84[mysqld]
85user=mysql
86port=3306
87character_set_server=utf8mb4
88secure_file_priv=
89server-id = 5733652
90log-bin =
91binlog_format=row
92gtid-mode=ON
93enforce-gtid-consistency=ON
94skip_name_resolve
95report_host=172.72.0.52
96default-time-zone = '+8:00'
97log_timestamps = SYSTEM
98log_slave_updates = 1
99master_info_repository='table'
100relay_log_info_repository='table'
101relay_log_recovery=1
102
103EOF
104
105-- 重启3台环境
106docker restart MSS57M33650 MSS57S33651 MSS57S33652
107docker ps
108
109[root@docker35 ~]# docker ps
110CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
111b6311aac4c08 mysql:5.7.36 "docker-entrypoint.s…" 6 seconds ago Up 3 seconds 33060/tcp, 0.0.0.0:33652->3306/tcp, :::33652->3306/tcp MSS57S33652
112b1f5f35c4fea mysql:5.7.36 "docker-entrypoint.s…" 11 seconds ago Up 8 seconds 33060/tcp, 0.0.0.0:33651->3306/tcp, :::33651->3306/tcp MSS57S33651
1139a9826423f2d mysql:5.7.36 "docker-entrypoint.s…" 17 seconds ago Up 15 seconds 33060/tcp, 0.0.0.0:33650->3306/tcp, :::33650->3306/tcp MSS57M33650
114
115-- 登陆
116docker exec -it MSS57M33650 bash
117docker exec -it MSS57M33650 mysql -uroot -plhr
118
119-- 查询
120mysql -uroot -plhr -h192.168.88.35 -P33650 -e "select @@hostname,@@server_id,@@server_uuid"
121mysql -uroot -plhr -h192.168.88.35 -P33651 -e "select @@hostname,@@server_id,@@server_uuid"
122mysql -uroot -plhr -h192.168.88.35 -P33652 -e "select @@hostname,@@server_id,@@server_uuid"
123
124C:\Users\lhrxxt>mysql -uroot -plhr -h192.168.88.35 -P33650 -e "select @@hostname,@@server_id,@@server_uuid"
125mysql: [Warning] Using a password on the command line interface can be insecure.
126+------------+-------------+--------------------------------------+
127| @@hostname | @@server_id | @@server_uuid |
128+------------+-------------+--------------------------------------+
129| master | 5733650 | a5c6a094-dbf1-11ec-8f03-0242ac480032 |
130+------------+-------------+--------------------------------------+
131
132C:\Users\lhrxxt>mysql -uroot -plhr -h192.168.88.35 -P33651 -e "select @@hostname,@@server_id,@@server_uuid"
133mysql: [Warning] Using a password on the command line interface can be insecure.
134+------------+-------------+--------------------------------------+
135| @@hostname | @@server_id | @@server_uuid |
136+------------+-------------+--------------------------------------+
137| slave1 | 5733651 | a99e5d38-dbf1-11ec-bfe9-0242ac480033 |
138+------------+-------------+--------------------------------------+
139
140C:\Users\lhrxxt>mysql -uroot -plhr -h192.168.88.35 -P33652 -e "select @@hostname,@@server_id,@@server_uuid"
141mysql: [Warning] Using a password on the command line interface can be insecure.
142+------------+-------------+--------------------------------------+
143| @@hostname | @@server_id | @@server_uuid |
144+------------+-------------+--------------------------------------+
145| slave2 | 5733652 | ac918575-dbf1-11ec-b236-0242ac480034 |
146+------------+-------------+--------------------------------------+
2、主库配置
1-- 主库创建复制用户repl
2mysql -uroot -plhr -h192.168.88.35 -P33650
3grant replication slave on *.* to repl@'%' identified by 'lhr';
4select user,host,grant_priv,password_last_changed,authentication_string from mysql.user;
5
6create database lhrdb;
7use lhrdb;
8create table mytb1(id int,name varchar(30));
9insert into mytb1 values(1,'a'),(2,'b');
10
11
12-- 安装插件
13INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
14INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
15SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME LIKE '%semi%';
16
17-- 配置参数,后期需要配置到参数文件中去
18set global rpl_semi_sync_master_enabled=on;
19
20-- 查询
21show master status ;
22show slave hosts;
23select @@hostname,@@server_id,@@server_uuid;
执行过程:
1MySQL [lhrdb]> show master status ;
2+-------------------+----------+--------------+------------------+------------------------------------------+
3| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
4+-------------------+----------+--------------+------------------+------------------------------------------+
5| master-bin.000004 | 1085 | | | 1bc15639-bc5b-11eb-b1eb-0242ac480032:1-9 |
6+-------------------+----------+--------------+------------------+------------------------------------------+
71 row in set (0.06 sec)
8
9MySQL [lhrdb]> show slave hosts;
10Empty set (0.06 sec)
11
12MySQL [lhrdb]> select @@hostname,@@server_id,@@server_uuid;
13+------------+-------------+--------------------------------------+
14| @@hostname | @@server_id | @@server_uuid |
15+------------+-------------+--------------------------------------+
16| master | 5733650 | 1bc15639-bc5b-11eb-b1eb-0242ac480032 |
17+------------+-------------+--------------------------------------+
181 row in set (0.05 sec)
19
20
21MySQL [lhrdb]> INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
22Query OK, 0 rows affected (0.08 sec)
23
24MySQL [(none)]> INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
25Query OK, 0 rows affected (0.08 sec)
26
27MySQL [lhrdb]> SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME LIKE '%semi%';
28+----------------------+---------------+
29| PLUGIN_NAME | PLUGIN_STATUS |
30+----------------------+---------------+
31| rpl_semi_sync_master | ACTIVE |
32| rpl_semi_sync_slave | ACTIVE |
33+----------------------+---------------+
342 rows in set (0.00 sec)
35
36MySQL [lhrdb]> set global rpl_semi_sync_master_enabled=on;
37Query OK, 0 rows affected (0.05 sec)
38
39MySQL [lhrdb]> show variables like '%semi%';
40+-------------------------------------------+------------+
41| Variable_name | Value |
42+-------------------------------------------+------------+
43| rpl_semi_sync_master_enabled | ON |
44| rpl_semi_sync_master_timeout | 10000 |
45| rpl_semi_sync_master_trace_level | 32 |
46| rpl_semi_sync_master_wait_for_slave_count | 1 |
47| rpl_semi_sync_master_wait_no_slave | ON |
48| rpl_semi_sync_master_wait_point | AFTER_SYNC |
49| rpl_semi_sync_slave_enabled | OFF |
50| rpl_semi_sync_slave_trace_level | 32 |
51+-------------------------------------------+------------+
528 rows in set (0.01 sec)
3、从库1配置
1-- 从库1
2mysql -uroot -plhr -h192.168.88.35 -P33651
3
4-- 安装插件
5INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
6INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
7SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME LIKE '%semi%';
8
9
10-- 配置参数,后期需要配置到参数文件中去
11set global rpl_semi_sync_slave_enabled=on;
12
13
14-- 修改参数
15change master to
16master_host='172.72.0.50',
17master_port=3306,
18master_user='repl',
19master_password='lhr',
20master_auto_position=1;
21
22-- 启动复制进程
23start slave;
24show slave status \G;
25
26SELECT * FROM lhrdb.mytb1;
27
28-- 主库:
29insert into mytb1 values(3,'c'),(4,'d');
4、从库2配置
1-- S2
2mysql -uroot -plhr -h192.168.88.35 -P33652
3
4
5
6-- 安装插件
7INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
8INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
9SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME LIKE '%semi%';
10
11-- 配置参数,后期需要配置到参数文件中去
12set global rpl_semi_sync_slave_enabled=on;
13
14
15-- 修改参数
16change master to master_host='172.72.0.50',
17master_port=3306,
18master_user='repl',
19master_password='lhr',
20master_auto_position=1;
21
22start slave;
23show slave status \G;
24
25SELECT * FROM lhrdb.mytb1;
5、主从查询
1-- 主库
2show slave hosts;
3show master status;
4show global status like 'rpl_semi%';
5show variables like '%Rpl%';
6
7-- 从库
8show slave status;
9show variables like '%Rpl%';
10
11
12
13-- 线程查询
14SELECT *
15FROM performance_schema.threads a
16WHERE a.`NAME` IN ( 'thread/sql/slave_IO', 'thread/sql/slave_sql' ) or a.PROCESSLIST_COMMAND in ('Binlog Dump','Binlog Dump GTID') ;
17
18SELECT * FROM information_schema.`PROCESSLIST` a where a.USER='system user' or a.command in ('Binlog Dump','Binlog Dump GTID') ;
半同步复制查询:
1-- 主库
2MySQL [lhrdb]> show global status like 'rpl_semi%';
3+--------------------------------------------+-------+
4| Variable_name | Value |
5+--------------------------------------------+-------+
6| Rpl_semi_sync_master_clients | 2 |
7| Rpl_semi_sync_master_net_avg_wait_time | 0 |
8| Rpl_semi_sync_master_net_wait_time | 0 |
9| Rpl_semi_sync_master_net_waits | 1 |
10| Rpl_semi_sync_master_no_times | 0 |
11| Rpl_semi_sync_master_no_tx | 0 |
12| Rpl_semi_sync_master_status | ON |
13| Rpl_semi_sync_master_timefunc_failures | 0 |
14| Rpl_semi_sync_master_tx_avg_wait_time | 747 |
15| Rpl_semi_sync_master_tx_wait_time | 747 |
16| Rpl_semi_sync_master_tx_waits | 1 |
17| Rpl_semi_sync_master_wait_pos_backtraverse | 0 |
18| Rpl_semi_sync_master_wait_sessions | 0 |
19| Rpl_semi_sync_master_yes_tx | 1 |
20| Rpl_semi_sync_slave_status | OFF |
21+--------------------------------------------+-------+
2215 rows in set (0.01 sec)
23
24MySQL [lhrdb]> show variables like '%Rpl%';
25+-------------------------------------------+------------+
26| Variable_name | Value |
27+-------------------------------------------+------------+
28| rpl_semi_sync_master_enabled | ON |
29| rpl_semi_sync_master_timeout | 10000 |
30| rpl_semi_sync_master_trace_level | 32 |
31| rpl_semi_sync_master_wait_for_slave_count | 1 |
32| rpl_semi_sync_master_wait_no_slave | ON |
33| rpl_semi_sync_master_wait_point | AFTER_SYNC |
34| rpl_semi_sync_slave_enabled | OFF |
35| rpl_semi_sync_slave_trace_level | 32 |
36| rpl_stop_slave_timeout | 31536000 |
37+-------------------------------------------+------------+
389 rows in set (0.09 sec)
39
40-- 从库
41MySQL [(none)]> show global status like 'Rpl_semi_sync_slave_status%';
42+----------------------------+-------+
43| Variable_name | Value |
44+----------------------------+-------+
45| Rpl_semi_sync_slave_status | ON |
46+----------------------------+-------+
471 row in set (0.05 sec)
Rpl_semi_sync_master_clients表示记录支持半同步的slave的个数
Rpl_semi_sync_master_status标记master现在是否是半同步复制状态
6、测试半同步复制
测试过程:
1、关闭从库io线程,模拟网络卡顿
2、主库插入数据,等待10秒,同步方式自动转换为异步模式
3、从库启动io线程
4、同步方式变为半同步模式
先关闭一个从库,我们测试1主1从的情况。
二、配置延迟复制示例
我们把从库2配置为延迟从库,如下所示:
1STOP SLAVE SQL_THREAD;
2CHANGE MASTER TO MASTER_DELAY = 120;
3START SLAVE SQL_THREAD;
4
5show slave status \G
6返回:SQL_Delay: 120
7
8
9-- 主库插入数据
10insert into mytb1 values(5,'e'),(6,'f');
11select * from mytb1;
12
13-- 从库2查询
14show slave status \G
15
16Seconds_Behind_Master: 110
17SQL_Remaining_Delay: 46
18Slave_SQL_Running_State: Waiting until MASTER_DELAY seconds after master executed event
三、配置并行复制示例
3.1、主库配置
1set global binlog_group_commit_sync_delay=10;
2set global binlog_group_commit_sync_no_delay_count=10;
3show variables like 'binlog_group_commit_sync_%';
3.2、从库2配置并行复制
只在从库2做配置,从库1不做配置。
1STOP SLAVE SQL_THREAD;
2set global slave_parallel_type=LOGICAL_CLOCK;
3set global slave_parallel_workers=4;
4
5show variables like 'slave_parallel%';
6
7start SLAVE SQL_THREAD;
8
9-- 线程查询
10SELECT *
11FROM performance_schema.threads a
12WHERE a.`NAME` IN ( 'thread/sql/slave_IO', 'thread/sql/slave_sql','thread/sql/slave_worker' ) or a.PROCESSLIST_COMMAND in ('Binlog Dump','Binlog Dump GTID') ;
13
14SELECT * FROM information_schema.`PROCESSLIST` a where a.USER='system user' or a.command in ('Binlog Dump','Binlog Dump GTID') ;
15
16
17MySQL [(none)]> SELECT *
18 -> FROM performance_schema.threads a
19 -> WHERE a.`NAME` IN ( 'thread/sql/slave_IO', 'thread/sql/slave_sql','thread/sql/slave_worker' ) or a.PROCESSLIST_COMMAND in ('Binlog Dump','Binlog Dump GTID') ;
20+-----------+-------------------------+------------+----------------+------------------+------------------+----------------+---------------------+------------------+--------------------------------------------------------+------------------+------------------+------+--------------+---------+-----------------+--------------+
21| THREAD_ID | NAME | TYPE | PROCESSLIST_ID | PROCESSLIST_USER | PROCESSLIST_HOST | PROCESSLIST_DB | PROCESSLIST_COMMAND | PROCESSLIST_TIME | PROCESSLIST_STATE | PROCESSLIST_INFO | PARENT_THREAD_ID | ROLE | INSTRUMENTED | HISTORY | CONNECTION_TYPE | THREAD_OS_ID |
22+-----------+-------------------------+------------+----------------+------------------+------------------+----------------+---------------------+------------------+--------------------------------------------------------+------------------+------------------+------+--------------+---------+-----------------+--------------+
23| 33 | thread/sql/slave_io | FOREGROUND | 8 | root | 172.72.0.1 | NULL | Connect | 1203 | Waiting for master to send event | NULL | 30 | NULL | YES | YES | NULL | 79 |
24| 36 | thread/sql/slave_sql | FOREGROUND | 11 | root | 172.72.0.1 | NULL | Connect | 312 | Slave has read all relay log; waiting for more updates | NULL | 30 | NULL | YES | YES | NULL | 82 |
25| 37 | thread/sql/slave_worker | FOREGROUND | 12 | root | 172.72.0.1 | NULL | Connect | 312 | Waiting for an event from Coordinator | NULL | 36 | NULL | YES | YES | NULL | 83 |
26| 38 | thread/sql/slave_worker | FOREGROUND | 13 | root | 172.72.0.1 | NULL | Connect | 312 | Waiting for an event from Coordinator | NULL | 36 | NULL | YES | YES | NULL | 84 |
27| 39 | thread/sql/slave_worker | FOREGROUND | 14 | root | 172.72.0.1 | NULL | Connect | 312 | Waiting for an event from Coordinator | NULL | 36 | NULL | YES | YES | NULL | 85 |
28| 40 | thread/sql/slave_worker | FOREGROUND | 15 | root | 172.72.0.1 | NULL | Connect | 312 | Waiting for an event from Coordinator | NULL | 36 | NULL | YES | YES | NULL | 86 |
29+-----------+-------------------------+------------+----------------+------------------+------------------+----------------+---------------------+------------------+--------------------------------------------------------+------------------+------------------+------+--------------+---------+-----------------+--------------+
306 rows in set (0.05 sec)
31
32MySQL [(none)]> SELECT * FROM information_schema.`PROCESSLIST` a where a.USER='system user' or a.command in ('Binlog Dump','Binlog Dump GTID') ;
33+----+-------------+------+------+---------+------+--------------------------------------------------------+------+
34| ID | USER | HOST | DB | COMMAND | TIME | STATE | INFO |
35+----+-------------+------+------+---------+------+--------------------------------------------------------+------+
36| 14 | system user | | NULL | Connect | 37 | Waiting for an event from Coordinator | NULL |
37| 15 | system user | | NULL | Connect | 37 | Waiting for an event from Coordinator | NULL |
38| 12 | system user | | NULL | Connect | 37 | Waiting for an event from Coordinator | NULL |
39| 13 | system user | | NULL | Connect | 37 | Waiting for an event from Coordinator | NULL |
40| 11 | system user | | NULL | Connect | 37 | Slave has read all relay log; waiting for more updates | NULL |
41| 8 | system user | | NULL | Connect | 928 | Waiting for master to send event | NULL |
42+----+-------------+------+------+---------+------+--------------------------------------------------------+------+
436 rows in set (0.05 sec)
3.3、主库压测测试并行复制
因为这里的架构为1主2从,我只配置了从库2为并行复制,从库1不是并行复制,那么接下来测试并行复制的效果。
首先,取消从库2的延迟复制功能:
1STOP SLAVE SQL_THREAD;
2CHANGE MASTER TO MASTER_DELAY = 0;
3START SLAVE SQL_THREAD;
4
5show slave status \G
6返回:SQL_Delay: 0
首先,主库进行压测生成数据:
1-- 主库修改
2set GLOBAL max_connections=10000;
3set global max_prepared_stmt_count=65536;
4
5-- 做压测
6sysbench /usr/share/sysbench/oltp_common.lua --time=300 --mysql-host=172.72.0.50 --mysql-port=3306 \
7--mysql-user=root --mysql-password=lhr --mysql-db=lhrdb --table-size=100000 --tables=10 \
8--threads=16 --events=999999999 prepare
9
10
11sysbench /usr/share/sysbench/oltp_read_write.lua --time=300 --mysql-host=172.72.0.50 --mysql-port=3306 \
12--mysql-user=root --mysql-password=lhr --mysql-db=lhrdb --table-size=1000000 --tables=10 --threads=16 \
13--events=999999999 --report-interval=10 --db-ps-mode=disable --forced-shutdown=1 run
14
15
16
17-- 查询从库
18mysql -uroot -plhr -h192.168.88.35 -P33651 -e "show slave status \G" | grep Seconds_Behind_Master
19mysql -uroot -plhr -h192.168.88.35 -P33652 -e "show slave status \G" | grep Seconds_Behind_Master
20
结果:
1[root@docker35 ~]# mysql -uroot -plhr -h192.168.88.35 -P33651 -e "show slave status \G" | grep Seconds_Behind_Master
2mysql: [Warning] Using a password on the command line interface can be insecure.
3 Seconds_Behind_Master: 126
4[root@docker35 ~]# mysql -uroot -plhr -h192.168.88.35 -P33652 -e "show slave status \G" | grep Seconds_Behind_Master
5mysql: [Warning] Using a password on the command line interface can be insecure.
6 Seconds_Behind_Master: 62
7[root@docker35 ~]#
8[root@docker35 ~]# mysql -uroot -plhr -h192.168.88.35 -P33651 -e "show slave status \G" | grep Seconds_Behind_Master
9mysql: [Warning] Using a password on the command line interface can be insecure.
10 Seconds_Behind_Master: 139
11[root@docker35 ~]# mysql -uroot -plhr -h192.168.88.35 -P33652 -e "show slave status \G" | grep Seconds_Behind_Master
12mysql: [Warning] Using a password on the command line interface can be insecure.
13 Seconds_Behind_Master: 65
14[root@docker35 ~]#
15[root@docker35 ~]# mysql -uroot -plhr -h192.168.88.35 -P33651 -e "show slave status \G" | grep Seconds_Behind_Master
16mysql: [Warning] Using a password on the command line interface can be insecure.
17 Seconds_Behind_Master: 214
18[root@docker35 ~]# mysql -uroot -plhr -h192.168.88.35 -P33652 -e "show slave status \G" | grep Seconds_Behind_Master
19mysql: [Warning] Using a password on the command line interface can be insecure.
20 Seconds_Behind_Master: 78
可以看到,从库2比从库1能至少快一倍。
若是将从库的slave_parallel_workers配置为16,则配置了并行复制的库基本无延迟,而没有配置并行复制的库,延迟会越来越严重:
1STOP SLAVE SQL_THREAD;
2set global slave_parallel_workers=16;
3
4show variables like 'slave_parallel%';
5
6start SLAVE SQL_THREAD;
7
8-- 线程查询
9SELECT *
10FROM performance_schema.threads a
11WHERE a.`NAME` IN ( 'thread/sql/slave_IO', 'thread/sql/slave_sql','thread/sql/slave_worker' ) or a.PROCESSLIST_COMMAND in ('Binlog Dump','Binlog Dump GTID') ;
12
13SELECT * FROM information_schema.`PROCESSLIST` a where a.USER='system user' or a.command in ('Binlog Dump','Binlog Dump GTID') ;
14
15
16MySQL [lhrdb]> -- 线程查询
17MySQL [lhrdb]> SELECT *
18 -> FROM performance_schema.threads a
19 -> WHERE a.`NAME` IN ( 'thread/sql/slave_IO', 'thread/sql/slave_sql','thread/sql/slave_worker' ) or a.PROCESSLIST_COMMAND in ('Binlog Dump','Binlog Dump GTID') ;
20+-----------+-------------------------+------------+----------------+------------------+------------------+----------------+---------------------+------------------+--------------------------------------------------------+------------------+------------------+------+--------------+---------+-----------------+--------------+
21| THREAD_ID | NAME | TYPE | PROCESSLIST_ID | PROCESSLIST_USER | PROCESSLIST_HOST | PROCESSLIST_DB | PROCESSLIST_COMMAND | PROCESSLIST_TIME | PROCESSLIST_STATE | PROCESSLIST_INFO | PARENT_THREAD_ID | ROLE | INSTRUMENTED | HISTORY | CONNECTION_TYPE | THREAD_OS_ID |
22+-----------+-------------------------+------------+----------------+------------------+------------------+----------------+---------------------+------------------+--------------------------------------------------------+------------------+------------------+------+--------------+---------+-----------------+--------------+
23| 29 | thread/sql/slave_io | FOREGROUND | 4 | root | 192.168.88.64 | NULL | Connect | 1780 | Waiting for master to send event | NULL | 28 | NULL | YES | YES | NULL | 154 |
24| 106 | thread/sql/slave_sql | FOREGROUND | 81 | root | 192.168.88.64 | NULL | Connect | 24 | Slave has read all relay log; waiting for more updates | NULL | 28 | NULL | YES | YES | NULL | 168 |
25| 107 | thread/sql/slave_worker | FOREGROUND | 82 | root | 192.168.88.64 | NULL | Connect | 322 | Waiting for an event from Coordinator | BEGIN | 106 | NULL | YES | YES | NULL | 169 |
26| 108 | thread/sql/slave_worker | FOREGROUND | 83 | root | 192.168.88.64 | NULL | Connect | 322 | Waiting for an event from Coordinator | BEGIN | 106 | NULL | YES | YES | NULL | 170 |
27| 109 | thread/sql/slave_worker | FOREGROUND | 84 | root | 192.168.88.64 | NULL | Connect | 322 | Waiting for an event from Coordinator | BEGIN | 106 | NULL | YES | YES | NULL | 171 |
28| 110 | thread/sql/slave_worker | FOREGROUND | 85 | root | 192.168.88.64 | NULL | Connect | 322 | Waiting for an event from Coordinator | BEGIN | 106 | NULL | YES | YES | NULL | 172 |
29| 111 | thread/sql/slave_worker | FOREGROUND | 86 | root | 192.168.88.64 | NULL | Connect | 322 | Waiting for an event from Coordinator | BEGIN | 106 | NULL | YES | YES | NULL | 173 |
30| 112 | thread/sql/slave_worker | FOREGROUND | 87 | root | 192.168.88.64 | NULL | Connect | 322 | Waiting for an event from Coordinator | BEGIN | 106 | NULL | YES | YES | NULL | 174 |
31| 113 | thread/sql/slave_worker | FOREGROUND | 88 | root | 192.168.88.64 | NULL | Connect | 322 | Waiting for an event from Coordinator | BEGIN | 106 | NULL | YES | YES | NULL | 175 |
32| 114 | thread/sql/slave_worker | FOREGROUND | 89 | root | 192.168.88.64 | NULL | Connect | 322 | Waiting for an event from Coordinator | BEGIN | 106 | NULL | YES | YES | NULL | 176 |
33| 115 | thread/sql/slave_worker | FOREGROUND | 90 | root | 192.168.88.64 | NULL | Connect | 322 | Waiting for an event from Coordinator | BEGIN | 106 | NULL | YES | YES | NULL | 177 |
34| 116 | thread/sql/slave_worker | FOREGROUND | 91 | root | 192.168.88.64 | NULL | Connect | 322 | Waiting for an event from Coordinator | BEGIN | 106 | NULL | YES | YES | NULL | 178 |
35| 117 | thread/sql/slave_worker | FOREGROUND | 92 | root | 192.168.88.64 | NULL | Connect | 322 | Waiting for an event from Coordinator | BEGIN | 106 | NULL | YES | YES | NULL | 179 |
36| 118 | thread/sql/slave_worker | FOREGROUND | 93 | root | 192.168.88.64 | NULL | Connect | 322 | Waiting for an event from Coordinator | BEGIN | 106 | NULL | YES | YES | NULL | 180 |
37| 119 | thread/sql/slave_worker | FOREGROUND | 94 | root | 192.168.88.64 | NULL | Connect | 322 | Waiting for an event from Coordinator | BEGIN | 106 | NULL | YES | YES | NULL | 181 |
38| 120 | thread/sql/slave_worker | FOREGROUND | 95 | root | 192.168.88.64 | NULL | Connect | 322 | Waiting for an event from Coordinator | BEGIN | 106 | NULL | YES | YES | NULL | 182 |
39| 121 | thread/sql/slave_worker | FOREGROUND | 96 | root | 192.168.88.64 | NULL | Connect | 322 | Waiting for an event from Coordinator | BEGIN | 106 | NULL | YES | YES | NULL | 183 |
40| 122 | thread/sql/slave_worker | FOREGROUND | 97 | root | 192.168.88.64 | NULL | Connect | 322 | Waiting for an event from Coordinator | BEGIN | 106 | NULL | YES | YES | NULL | 184 |
41+-----------+-------------------------+------------+----------------+------------------+------------------+----------------+---------------------+------------------+--------------------------------------------------------+------------------+------------------+------+--------------+---------+-----------------+--------------+
4218 rows in set (0.01 sec)
43
44MySQL [lhrdb]>
45MySQL [lhrdb]> SELECT * FROM information_schema.`PROCESSLIST` a where a.USER='system user' or a.command in ('Binlog Dump','Binlog Dump GTID') ;
46+----+-------------+------+------+---------+------+--------------------------------------------------------+------+
47| ID | USER | HOST | DB | COMMAND | TIME | STATE | INFO |
48+----+-------------+------+------+---------+------+--------------------------------------------------------+------+
49| 96 | system user | | NULL | Connect | 322 | Waiting for an event from Coordinator | NULL |
50| 97 | system user | | NULL | Connect | 322 | Waiting for an event from Coordinator | NULL |
51| 94 | system user | | NULL | Connect | 322 | Waiting for an event from Coordinator | NULL |
52| 95 | system user | | NULL | Connect | 322 | Waiting for an event from Coordinator | NULL |
53| 92 | system user | | NULL | Connect | 322 | Waiting for an event from Coordinator | NULL |
54| 93 | system user | | NULL | Connect | 322 | Waiting for an event from Coordinator | NULL |
55| 90 | system user | | NULL | Connect | 322 | Waiting for an event from Coordinator | NULL |
56| 91 | system user | | NULL | Connect | 322 | Waiting for an event from Coordinator | NULL |
57| 88 | system user | | NULL | Connect | 322 | Waiting for an event from Coordinator | NULL |
58| 89 | system user | | NULL | Connect | 322 | Waiting for an event from Coordinator | NULL |
59| 86 | system user | | NULL | Connect | 322 | Waiting for an event from Coordinator | NULL |
60| 87 | system user | | NULL | Connect | 322 | Waiting for an event from Coordinator | NULL |
61| 84 | system user | | NULL | Connect | 322 | Waiting for an event from Coordinator | NULL |
62| 82 | system user | | NULL | Connect | 322 | Waiting for an event from Coordinator | NULL |
63| 85 | system user | | NULL | Connect | 322 | Waiting for an event from Coordinator | NULL |
64| 83 | system user | | NULL | Connect | 322 | Waiting for an event from Coordinator | NULL |
65| 81 | system user | | NULL | Connect | 24 | Slave has read all relay log; waiting for more updates | NULL |
66| 4 | system user | | NULL | Connect | 1780 | Waiting for master to send event | NULL |
67+----+-------------+------+------+---------+------+--------------------------------------------------------+------+
6818 rows in set (0.01 sec)
重新测试,可以看到从库2基本无延迟了:
1[root@docker35 ~]# mysql -uroot -plhr -h192.168.88.35 -P33651 -e "show slave status \G" | grep Seconds_Behind_Master
2mysql: [Warning] Using a password on the command line interface can be insecure.
3 Seconds_Behind_Master: 50
4[root@docker35 ~]# mysql -uroot -plhr -h192.168.88.35 -P33652 -e "show slave status \G" | grep Seconds_Behind_Master
5mysql: [Warning] Using a password on the command line interface can be insecure.
6 Seconds_Behind_Master: 0
7[root@docker35 ~]#
8[root@docker35 ~]# mysql -uroot -plhr -h192.168.88.35 -P33651 -e "show slave status \G" | grep Seconds_Behind_Master
9mysql: [Warning] Using a password on the command line interface can be insecure.
10mysql -uroot -plhr -h192.168.88.35 -P33652 -e "show slave status \G" | grep Seconds_Behind_Master
11 Seconds_Behind_Master: 131
12[root@docker35 ~]# mysql -uroot -plhr -h192.168.88.35 -P33652 -e "show slave status \G" | grep Seconds_Behind_Master
13mysql: [Warning] Using a password on the command line interface can be insecure.
14 Seconds_Behind_Master: 1
15
16[root@docker35 ~]# mysql -uroot -plhr -h192.168.88.35 -P33651 -e "show slave status \G" | grep Seconds_Behind_Master
17mysql: [Warning] Using a password on the command line interface can be insecure.
18 Seconds_Behind_Master: 210
19[root@docker35 ~]# mysql -uroot -plhr -h192.168.88.35 -P33652 -e "show slave status \G" | grep Seconds_Behind_Master
20mysql: [Warning] Using a password on the command line interface can be insecure.
21 Seconds_Behind_Master: 1
22[root@docker35 ~]#
23[root@docker35 ~]# mysql -uroot -plhr -h192.168.88.35 -P33651 -e "show slave status \G" | grep Seconds_Behind_Master
24mysql -uroot -plhr -h192.168.88.35 -P33652 -e "show slave status \G" | grep Seconds_Behind_Mastermysql: [Warning] Using a password on the command line interface can be insecure.
25 Seconds_Behind_Master: 381
26[root@docker35 ~]# mysql -uroot -plhr -h192.168.88.35 -P33652 -e "show slave status \G" | grep Seconds_Behind_Master
27mysql: [Warning] Using a password on the command line interface can be insecure.
28 Seconds_Behind_Master: 1
29