• 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)

  • 相关阅读:
    函数调用时用const保护指针
    【译】介绍 MSTest Runner – CLI、Visual Studio 等
    VisualVM工具的使用
    Maven下载源码出现:Cannot download sources Sources not found for org.springframwork...
    C#导出本机Win32native dll
    三菱FX3U——ST局部标签和全局标签
    HackTheBox-Starting Point--Tier 1---Bike
    学习c++的第十三天
    19、Flink 的Table API 和 SQL 中的内置函数及示例(1)
    图片清晰度增强易语言代码
  • 原文地址:https://blog.csdn.net/liys0811/article/details/132827438