• mysql-5.7 调整mysql的复制方式由master_log_file+master_log_pos 到gtid 详解


    一、祖传的master_log_file + master_log_pos的复制方式面临的问题:

      在很久以前 那个时候我还没有出道,mysql就已经就有复制这个功能了。如果要告诉slave库从master二进制日志的哪个

      地方开始复制,就要通过change master to 的master_log_file & master_log_pos 参数来指定。但是这个有个问题,就

      是在slave出现问题后,slave要从那个地方开始重新同步呢?这个时候就比较小心了,因为show slave status 中对于文件

      名和位置的返回有三组。

    Master_Log_File: mysql-bin.000052
    Read_Master_Log_Pos: 190
    Relay_Log_File: 74cstudio-relay-bin.0000031
    Relay_Log_Pos: 355
    Relay_Master_Log_File: mysql-bin.000050
    Exec_Master_Log_Pos: 77

      如果dba在重新同步时指定的master_log_file + master_log_pos 参数不对,那么就会引起数据的不一致,而且这个不一致还

      不太好发现。

    二、gtid出现了:

      1、有了gtid了之后对于重新同步时slave从哪里开始同步master的binlog不在由dba来管了,省心了!

      2、有了gtid了之后只要对比一下master和slave上的gtid数据量就可以知道master和slave是否一致了!

    三、gtid这么吊 怎么建立一个基于gtid的复制呢?:

      根据官方文档要把复制方式从master_log_file + master_log_pos 换到基于gtid的复制,要经过如下几步:

      1、把master和slave都设置为read_only 这样做是为了slave能同步所有master上的已有更新,同步完成之后

      slave的数据量就是等于master的数据量了。

      2、关闭master 和 slave 

      3、开启master 和 slave 上的gtid功能 、开启read_only 功能。这都通过my.cnf文件配置下就行啦。

      4、启动master 和 slave 

      5、让slave 以gtid的方式同步

      6、设置master 和 slave 可写

    四、举例:

      还是先看一下已有master -> slave 环境的相关信息:

    mysql> show slave status G                                                                          
    *************************** 1. row ***************************
                   Slave_IO_State: Waiting for master to send event
                      Master_Host: 172.16.192.10
                      Master_User: repl
                      Master_Port: 3306
                    Connect_Retry: 60
                  Master_Log_File: mysql-bin.000005
              Read_Master_Log_Pos: 190
                   Relay_Log_File: 74cstudio-relay-bin.000003
                    Relay_Log_Pos: 355
            Relay_Master_Log_File: mysql-bin.000005
                 Slave_IO_Running: Yes
                Slave_SQL_Running: Yes

      1、设置master 和 slave 为只读: 

      master:

    Type 'help;' or 'h' for help. Type 'c' to clear the current input statement.
    
    mysql> set @@global.read_only=1;                                                                     
    Query OK, 0 rows affected (0.00 sec)

      slave:

    mysql> set @@global.read_only=1;                                                                     
    Query OK, 0 rows affected (0.00 sec)

      2、等slave完全同步了所有的master的更新后就关闭master 和 slave:

      master:

    [root@74cstudio mysql]# mysqladmin -uroot shutdown

      slave:

    [root@74cstudio mysql]# mysqladmin -uroot shutdown

      3、开启master 和 slave 上的gtid功能并把它们设置成read_only

      master

    [mysqld]
    gtid_executed_compression_period    =1000                          #    1000                         
    gtid_mode                           =on                            #    off                          
    enforce_gtid_consistency            =on                            #    off 
    read_only                           =1                              #   off

      slave

    [mysqld]
    gtid_executed_compression_period    =1000                          #    1000                         
    gtid_mode                           =on                            #    off                          
    enforce_gtid_consistency            =on                            #    off 
    read_only                           =1                              #   off

       4、启动master 和 slave 

      master

    [root@cstudio mysql]# systemctl start mysql

      slave

    [root@cstudio mysql]# systemctl start mysql

      5、让slave 以gtid的方式同步

      slave

    mysql>  change master to
        ->     master_host='172.16.192.10',
        ->     master_port=3306,
        ->     master_user='repl',
        ->     master_password='repl@352',
        ->     master_auto_position=1;
    Query OK, 0 rows affected, 2 warnings (0.00 sec)
    
    mysql> start slave;
    Query OK, 0 rows affected (0.00 sec)

      6、把master 和 slave 设置为可写

      master

    mysql> set @@global.read_only=0;                                                                     
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> show global variables like 'read_only';
    +---------------+-------+
    | Variable_name | Value |
    +---------------+-------+
    | read_only     | OFF   |
    +---------------+-------+

      slave

    mysql> set @@global.read_only=0;                                                                     
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> show global variables like 'read_only';
    +---------------+-------+
    | Variable_name | Value |
    +---------------+-------+
    | read_only     | OFF   |
    +---------------+-------+

      7、还是show slave status 看一下slave 同步的状态作为结束

    mysql> show slave status G                                                                          
    *************************** 1. row ***************************
                   Slave_IO_State: Waiting for master to send event
                      Master_Host: 172.16.192.10
                      Master_User: repl
                      Master_Port: 3306
                    Connect_Retry: 60
                  Master_Log_File: mysql-bin.000006
              Read_Master_Log_Pos: 509
                   Relay_Log_File: 74cstudio-relay-bin.000005
                    Relay_Log_Pos: 714
            Relay_Master_Log_File: mysql-bin.000006
                 Slave_IO_Running: Yes
                Slave_SQL_Running: Yes
                    Auto_Position: 1

    五、用gtid同步时可以方便的校对数据的一致性:

      master上看执行哪些事务

    mysql> show master status G                                                                         
    *************************** 1. row ***************************
                 File: mysql-bin.000006
             Position: 509
         Binlog_Do_DB: 
     Binlog_Ignore_DB: 
    Executed_Gtid_Set: 49d1e2c1-a8bc-11e7-8f4e-000c296c32b0:1-10
    1 row in set (0.00 sec)

      slave上看执行了哪些事务

    mysql> show master status G                                                                         
    *************************** 1. row ***************************
                 File: mysql-bin.000006
             Position: 509
         Binlog_Do_DB: 
     Binlog_Ignore_DB: 
    Executed_Gtid_Set: 49d1e2c1-a8bc-11e7-8f4e-000c296c32b0:1-10
    1 row in set (0.00 sec)

      由上面可以看出两次执行show master status G 的输出中Executed_Gtid_Set的值是一样的,说明master上的每一个事务都

      有在slave 上执行,所以可以得出master 和 slave是一致的结论。

    六、在执行master_log_file + master_log_pos 到 gtid 同步方式的变更时的注意项:

      1、在四.2中那个关闭master 和 slave 的时候一定要确定slave 已经应用了master 的所以变更。

      2、在四.4中最好先把slave设置成skip-slave-start=1 , 不然会发现在执行change master to 的时候会报slave 已经启动了

      当然这个报错可能通过先执行stop slave  然后再执行change master to 来规避。

    七、最后还是说一下什么是gtid

      gtid 这个哥们的中文全称叫 “全局事务ID”,说白了就是事务的“身份证号码”. 快10点了不想多说了。

    ----------------------------------------------------------------------

    -----------------------------------------------------------------------

    转载于:https://www.cnblogs.com/JiangLe/p/7635644.html

  • 相关阅读:
    数据库优化方案之分库分表
    聊聊ThreadLocal源码(基于JDK1.8)
    HashMap扩容死循环问题
    Synchronized偏向锁和轻量级锁的升级
    【Java并发编程之深入理解】Synchronized的使用
    ConcurrentHashMap 1.8为什么要使用CAS+Synchronized取代Segment+ReentrantLock
    面试必备技能:HashMap哪些技术点会被经常问到?
    序列键生成器及单例多例模式
    Effective.Java第1-11条
    抽象工厂(AbstractFactory)模式
  • 原文地址:https://www.cnblogs.com/twodog/p/12139261.html
Copyright © 2020-2023  润新知