Mysql主从复制之skip-slave-start,slave-parallel-type,slave-parallel-workers参数详解和测试

参数1)skip-slave-start = 0

参数详解:禁用skip-slave-start,slave进程会随着mysql启动而启动。skip-slave-start=1为开启

测试:当前slave的查不到该参数,且/etc/my.cnf也没有配置该文件,重启服务后,发现slave进程自动启动,且停服务期间master插入的数据也复制过来了,看了这个参数默认是skip-slave-start = 0

[root@localhost:mytest1]>show global variables like '%slave-start%';

Empty set (0.01 sec)

[mysql@t3-dtpoc-dtpoc-web05 bin]$ service mysql stop

Shutting down MySQL.. SUCCESS!

[mysql@t3-dtpoc-dtpoc-web05 bin]$ service mysql start

Starting MySQL. SUCCESS!

[root@localhost:mytest1]>show slave status\G;

Slave_IO_Running: Yes

Slave_SQL_Running: Yes

[root@localhost:mytest1]>select * from t1;

+------+------+

| id | name |

+------+------+

| 8888 | tsss |

| 9999 | jjjj |

+------+------+

2 rows in set (0.00 sec)

我们在/etc/my.cnf写入这个参数skip-slave-start=1,然后重启服务,发现slave进程没有自动启动,停服务期间master端插入的数据也没有复制过来,说明参数生效了,看起来这个参数好像没有什么用,因为我们总是希望备机重启时自动启动slave。但是如果因为主库一个没有主键的大表整表update或者delete,从库追平日志需要一个月时间,这个时候停掉slave没有任何反应,因为slave会把当前事务复制完才会停下来,类似于CDC的停复制停不下来需要强制停掉。这个时候重启数据库服务也无法停止,只能Kill -9 杀掉mysql进程,重启服务后发现slave又从头开始复制了,这个时候你怎么办?可以skip-slave-start=1,让slave不自动启动

[root@localhost:mytest1]>show slave status\G;

Slave_IO_Running: No

Slave_SQL_Running: No

[root@localhost:mytest1]>select * from t1;

+------+------+

| id | name |

+------+------+

| 8888 | tsss |

| 9999 | jjjj |

+------+------+

2 rows in set (0.00 sec)

参数2)slave-parallel-type = LOGICAL_CLOCK

slave-parallel-workers = 16

参数详解:mysql在5.7中加入了slave_parallel_type,默认值是database,需要改成基于时钟逻辑的LOGICAL_CLOCK。slave_parallel_workers数,默认为0,按需修改,可以根据服务器的配置来开启相应的并行度。将slave_parallel_type设置为'LOGICAL_CLOCK',slave_parallel_workers设置为大于0的值,即算是开启了并行复制

当前使用的是默认值:

[root@localhost:mytest1]>show variables like '%slave_parallel%';

+------------------------+----------+

| Variable_name | Value |

+------------------------+----------+

| slave_parallel_type | DATABASE |

| slave_parallel_workers | 0 |

+------------------------+----------+

2 rows in set (0.00 sec)

我们在/etc/my.cnf写入这个参数slave-parallel-type = LOGICAL_CLOCK,slave-parallel-workers = 16然后重启服务,发现已经有16个复制线程了

注意将这个database修改为logical_clock,在此之前,需要先关闭sql_thread

stop slave sql_thread;

set global slave_parallel_type='LOGICAL_CLOCK';

start slave sql_thread;

select * from performance_schema.replication_applier_status_by_worker;

[root@localhost:mytest1]>select * from performance_schema.replication_applier_status_by_worker;

+--------------+-----------+-----------+---------------+-----------------------+-------------------+--------------------+----------------------+

| CHANNEL_NAME | WORKER_ID | THREAD_ID | SERVICE_STATE | LAST_SEEN_TRANSACTION | LAST_ERROR_NUMBER | LAST_ERROR_MESSAGE | LAST_ERROR_TIMESTAMP |

+--------------+-----------+-----------+---------------+-----------------------+-------------------+--------------------+----------------------+

| | 1 | 27 | ON | ANONYMOUS | 0 | | 0000-00-00 00:00:00 |

| | 2 | 28 | ON | | 0 | | 0000-00-00 00:00:00 |

| | 3 | 29 | ON | | 0 | | 0000-00-00 00:00:00 |

| | 4 | 30 | ON | | 0 | | 0000-00-00 00:00:00 |

| | 5 | 31 | ON | | 0 | | 0000-00-00 00:00:00 |

| | 6 | 32 | ON | | 0 | | 0000-00-00 00:00:00 |

| | 7 | 33 | ON | | 0 | | 0000-00-00 00:00:00 |

| | 8 | 34 | ON | | 0 | | 0000-00-00 00:00:00 |

| | 9 | 35 | ON | | 0 | | 0000-00-00 00:00:00 |

| | 10 | 36 | ON | | 0 | | 0000-00-00 00:00:00 |

| | 11 | 39 | ON | | 0 | | 0000-00-00 00:00:00 |

| | 12 | 40 | ON | | 0 | | 0000-00-00 00:00:00 |

| | 13 | 41 | ON | | 0 | | 0000-00-00 00:00:00 |

| | 14 | 42 | ON | | 0 | | 0000-00-00 00:00:00 |

| | 15 | 43 | ON | | 0 | | 0000-00-00 00:00:00 |

| | 16 | 44 | ON | | 0 | | 0000-00-00 00:00:00 |

+--------------+-----------+-----------+---------------+-----------------------+-------------------+--------------------+----------------------+

16 rows in set (0.00 sec)

我们来测试下,对于没有主键的单表的全表更新有没有性能提升?我们之前做过测试对于Log_test的更新,可以看到5分钟的时间,从库更新了不到10000行数据(28300-8962=19338行)。

而开启并发以后发现5分钟的时间,从库更新了31228-14650=16578行,性能并没有提升。可以分析是因为对于一个事务只能有一个线程执行,所有并没有触发并发

[root@localhost:mytest1]>set transaction_isolation='READ-UNCOMMITTED';

Query OK, 0 rows affected (0.00 sec)

[root@localhost:mytest1]>select now();

+---------------------+

| now() |

+---------------------+

| 2023-09-12 10:34:24 |

+---------------------+

1 row in set (0.00 sec)

[root@localhost:mytest1]>select count(*) from log_test where id>80000000;

+----------+

| count(*) |

+----------+

| 14650 |

+----------+

1 row in set (2.18 sec)

[root@localhost:mytest1]>select now();

+---------------------+

| now() |

+---------------------+

| 2023-09-12 10:39:24 |

+---------------------+

1 row in set (0.00 sec)

[root@localhost:mytest1]>select count(*) from log_test where id>80000000;

+----------+

| count(*) |

+----------+

| 31228 |

+----------+

1 row in set (3.04 sec)

我们来测试下,对于没有主键的两个表的全表更新,从库会不会两张表并发复制?复制效率怎么样?

主端插入log_test400W行数据,然后创建表log_test1,再插入log_test1 400W行,发现从库只有把log_test400W行数据全复制完后才会创建log_test1然后再插入,说明并发复制并不会并发事务

[root@localhost:mytest1]>select count(*) from log_test1;

ERROR 1146 (42S02): Table 'mytest1.log_test1' doesn't exist

[root@localhost:mytest1]>select count(*) from log_test;

+----------+

| count(*) |

+----------+

| 8000000 |

+----------+

1 row in set (5.26 sec)

[root@localhost:mytest1]>select count(*) from log_test1;

+----------+

| count(*) |

+----------+

| 299012 |

+----------+

1 row in set (0.13 sec)

再次确认并发是打开的,主库更新两张表后,从库一直在更新一张表,说明事务并没有并发,这和预期不符啊,这算什么并发啊。

[root@localhost:mytest1]>select * from performance_schema.replication_applier_status_by_worker;

+--------------+-----------+-----------+---------------+-----------------------+-------------------+--------------------+----------------------+

| CHANNEL_NAME | WORKER_ID | THREAD_ID | SERVICE_STATE | LAST_SEEN_TRANSACTION | LAST_ERROR_NUMBER | LAST_ERROR_MESSAGE | LAST_ERROR_TIMESTAMP |

+--------------+-----------+-----------+---------------+-----------------------+-------------------+--------------------+----------------------+

| | 1 | 31 | ON | ANONYMOUS | 0 | | 0000-00-00 00:00:00 |

| | 2 | 32 | ON | | 0 | | 0000-00-00 00:00:00 |

| | 3 | 33 | ON | | 0 | | 0000-00-00 00:00:00 |

| | 4 | 34 | ON | | 0 | | 0000-00-00 00:00:00 |

| | 5 | 35 | ON | | 0 | | 0000-00-00 00:00:00 |

| | 6 | 36 | ON | | 0 | | 0000-00-00 00:00:00 |

| | 7 | 37 | ON | | 0 | | 0000-00-00 00:00:00 |

| | 8 | 38 | ON | | 0 | | 0000-00-00 00:00:00 |

| | 9 | 39 | ON | | 0 | | 0000-00-00 00:00:00 |

| | 10 | 40 | ON | | 0 | | 0000-00-00 00:00:00 |

| | 11 | 41 | ON | | 0 | | 0000-00-00 00:00:00 |

| | 12 | 42 | ON | | 0 | | 0000-00-00 00:00:00 |

| | 13 | 43 | ON | | 0 | | 0000-00-00 00:00:00 |

| | 14 | 44 | ON | | 0 | | 0000-00-00 00:00:00 |

| | 15 | 45 | ON | | 0 | | 0000-00-00 00:00:00 |

| | 16 | 46 | ON | | 0 | | 0000-00-00 00:00:00 |

+--------------+-----------+-----------+---------------+-----------------------+-------------------+--------------------+----------------------+

16 rows in set (0.00 sec)

[root@localhost:mytest1]>select count(*) from log_test where id>80000000;

+----------+

| count(*) |

+----------+

| 20970 |

+----------+

1 row in set (4.55 sec)

[root@localhost:mytest1]>select count(*) from log_test1 where id>80000000;

+----------+

| count(*) |

+----------+

| 0 |

+----------+

1 row in set (2.29 sec)

我们注意到只有第一个线程的LAST_ERROR_NUMBER不为空是ANONYMOUS,有可能是gtid_mode是OFF导致不能并发,接下来继续测试

[root@localhost:mytest1]>show variables like '%gtid_mode%';

+---------------+-------+

| Variable_name | Value |

+---------------+-------+

| gtid_mode | OFF |

+---------------+-------+

1 row in set (0.00 sec)

在主库和从库的/etc/my.cnf都写入GTID的设置,然后重启服务,测试无主键的单表全表更新发现还是单线程在复制该事务,5分钟的时间,从库更新了28767-5280=23487行

#GTID相关

enforce_gtid_consistency = 1

gtid_mode = on

[root@localhost:mytest1]>show variables like '%gtid_mode%';

+---------------+-------+

| Variable_name | Value |

+---------------+-------+

| gtid_mode | ON |

+---------------+-------+

1 row in set (0.01 sec)

[root@localhost:mytest1]>select now();

+---------------------+

| now() |

+---------------------+

| 2023-09-12 14:07:39 |

+---------------------+

1 row in set (0.00 sec)

[root@localhost:mytest1]>select count(*) from log_test where id>80000000;

+----------+

| count(*) |

+----------+

| 5280 |

+----------+

1 row in set (2.44 sec)

[root@localhost:mytest1]>select now();

+---------------------+

| now() |

+---------------------+

| 2023-09-12 14:12:39 |

+---------------------+

1 row in set (0.00 sec)

[root@localhost:mytest1]>select count(*) from log_test where id>80000000;

+----------+

| count(*) |

+----------+

| 28767 |

+----------+

1 row in set (2.30 sec)

[root@localhost:mytest1]>select * from performance_schema.replication_applier_status_by_worker;

+--------------+-----------+-----------+---------------+----------------------------------------+-------------------+--------------------+----------------------+

| CHANNEL_NAME | WORKER_ID | THREAD_ID | SERVICE_STATE | LAST_SEEN_TRANSACTION | LAST_ERROR_NUMBER | LAST_ERROR_MESSAGE | LAST_ERROR_TIMESTAMP |

+--------------+-----------+-----------+---------------+----------------------------------------+-------------------+--------------------+----------------------+

| | 1 | 32 | ON | 6797f03c-2122-11ee-842b-00505695c6d5:8 | 0 | | 0000-00-00 00:00:00 |

| | 2 | 33 | ON | | 0 | | 0000-00-00 00:00:00 |

| | 3 | 34 | ON | | 0 | | 0000-00-00 00:00:00 |

| | 4 | 35 | ON | | 0 | | 0000-00-00 00:00:00 |

| | 5 | 36 | ON | | 0 | | 0000-00-00 00:00:00 |

| | 6 | 37 | ON | | 0 | | 0000-00-00 00:00:00 |

| | 7 | 38 | ON | | 0 | | 0000-00-00 00:00:00 |

| | 8 | 39 | ON | | 0 | | 0000-00-00 00:00:00 |

| | 9 | 40 | ON | | 0 | | 0000-00-00 00:00:00 |

| | 10 | 41 | ON | | 0 | | 0000-00-00 00:00:00 |

| | 11 | 42 | ON | | 0 | | 0000-00-00 00:00:00 |

| | 12 | 43 | ON | | 0 | | 0000-00-00 00:00:00 |

| | 13 | 44 | ON | | 0 | | 0000-00-00 00:00:00 |

| | 14 | 45 | ON | | 0 | | 0000-00-00 00:00:00 |

| | 15 | 46 | ON | | 0 | | 0000-00-00 00:00:00 |

| | 16 | 47 | ON | | 0 | | 0000-00-00 00:00:00 |

+--------------+-----------+-----------+---------------+----------------------------------------+-------------------+--------------------+----------------------+

16 rows in set (0.00 sec)

我们来测试下,对于没有主键的两个表的全表更新,发现还是单线程在工作,执行完插入log_test的事务才开始执行插入Log_test1的事务,并没有并发。

[root@localhost:mytest1]>select * from performance_schema.replication_applier_status_by_worker;

+--------------+-----------+-----------+---------------+-----------------------------------------+-------------------+--------------------+----------------------+

| CHANNEL_NAME | WORKER_ID | THREAD_ID | SERVICE_STATE | LAST_SEEN_TRANSACTION | LAST_ERROR_NUMBER | LAST_ERROR_MESSAGE | LAST_ERROR_TIMESTAMP |

+--------------+-----------+-----------+---------------+-----------------------------------------+-------------------+--------------------+----------------------+

| | 1 | 32 | ON | 6797f03c-2122-11ee-842b-00505695c6d5:11 | 0 | | 0000-00-00 00:00:00 |

| | 2 | 33 | ON | | 0 | | 0000-00-00 00:00:00 |

| | 3 | 34 | ON | | 0 | | 0000-00-00 00:00:00 |

| | 4 | 35 | ON | | 0 | | 0000-00-00 00:00:00 |

| | 5 | 36 | ON | | 0 | | 0000-00-00 00:00:00 |

| | 6 | 37 | ON | | 0 | | 0000-00-00 00:00:00 |

| | 7 | 38 | ON | | 0 | | 0000-00-00 00:00:00 |

| | 8 | 39 | ON | | 0 | | 0000-00-00 00:00:00 |

| | 9 | 40 | ON | | 0 | | 0000-00-00 00:00:00 |

| | 10 | 41 | ON | | 0 | | 0000-00-00 00:00:00 |

| | 11 | 42 | ON | | 0 | | 0000-00-00 00:00:00 |

| | 12 | 43 | ON | | 0 | | 0000-00-00 00:00:00 |

| | 13 | 44 | ON | | 0 | | 0000-00-00 00:00:00 |

| | 14 | 45 | ON | | 0 | | 0000-00-00 00:00:00 |

| | 15 | 46 | ON | | 0 | | 0000-00-00 00:00:00 |

| | 16 | 47 | ON | | 0 | | 0000-00-00 00:00:00 |

+--------------+-----------+-----------+---------------+-----------------------------------------+-------------------+--------------------+----------------------+

16 rows in set (0.00 sec)

[root@localhost:mytest1]>select count(*) from log_test;

+----------+

| count(*) |

+----------+

| 872638 |

+----------+

1 row in set (0.47 sec)

[root@localhost:mytest1]>select count(*) from log_test1;

+----------+

| count(*) |

+----------+

| 0 |

+----------+

1 row in set (0.00 sec)

相关推荐
落落落sss4 小时前
MQ集群
java·服务器·开发语言·后端·elasticsearch·adb·ruby
运维佬16 小时前
在 MySQL 8.0 中,SSL 解密失败,在使用 SSL 加密连接时出现了问题
mysql·adb·ssl
qq_308957472 天前
adb 如何通过wifi连接手机
adb·智能手机·app自动化测试
白如意i2 天前
如何在 CentOS 6 上设置 NFS 挂载
数据库·mysql·adb
七月.末2 天前
安卓aab包的安装教程,附带adb环境的配置
android·adb
SRC_BLUE_173 天前
SQLI LABS | Less-39 GET-Stacked Query Injection-Intiger Based
android·网络安全·adb·less
jason.zeng@15022074 天前
ubuntu中安装mysql
mysql·ubuntu·adb
看山还是山,看水还是。4 天前
MySQL 安装
运维·数据库·笔记·学习·mysql·adb
开心呆哥5 天前
【如何使用 Python 脚本通过 ADB 命令来检查 Android 文件内容】
android·python·adb
秋秋秋秋秋雨6 天前
linux强制修改mysql的root账号密码
linux·mysql·adb