zoukankan      html  css  js  c++  java
  • MySQL GTID

    【Global Transaction ID】
    GTID(Global Transaction ID)是对于一个已提交事务的编号,并且是一个全局唯一的编号。
    GTID实际上是由UUID+TID组成的。其中UUID是一个MySQL实例的唯一标识。TID代表了该实例上已经提交的事务数量,并且随着事务提交单调递增。下面是一个GTID的具体形式

    3E11FA47-71CA-11E1-9E33-C80AA9429562:23

     

                                               gtid event 结构

    • GTID的作用

          那么GTID功能的目的是什么呢?具体归纳主要有以下两点:

          GTID目的在于使用GTID的MySQL能够在整个复制环境中能够自动地切换,而不像以前需要指定文件和位置

    1. 根据GTID可以知道事务最初是在哪个实例上提交的
    2. GTID的存在方便了Replication的Failover

          MySQL 5.6的GTID出现以前replication failover的操作过程:

          

           Master节点Server A的服务器宕机,需要将业务切换到Server B上。同时,我们又需要将Server C的复制源改成Server B。复制源修改的命令语法很简单即CHANGE MASTER TO MASTER_HOST='xxx', MASTER_LOG_FILE='xxx', MASTER_LOG_POS=nnnn。

           而难点在于,由于同一个事务在每台机器上所在的binlog名字和位置都不一样,那么怎么找到Server C当前同步停止点,对应Server B的master_log_file和master_log_pos是什么的时候就成为了难题。这也就是为什么M-S复制集群需要使用MMM,MHA这样的额外管理工具的一个重要原因。
           这个问题在5.6的GTID出现后,就显得非常的简单。由于同一事务的GTID在所有节点上的值一致,那么根据Server C当前停止点的GTID就能唯一定位到Server B上的GTID。甚至由于MASTER_AUTO_POSITION功能的出现,我们都不需要知道GTID的具体值,直接使用CHANGE MASTER TO MASTER_HOST='xxx', MASTER_AUTO_POSITION命令就可以直接完成failover的工作。

    • 如何从classic replication 升级成 GTID replication

           1)offline 方式升级

           offline 的方式升级最简单。全部关机,然后配置好GTID,重启,change master to MASTER_AUTO_POSITION=1。
           2)online 方式升级

    step 1: 每台server执行 > 检查错误日志,直到没有错误出现,才能进行下一步
    SET @@GLOBAL.ENFORCE_GTID_CONSISTENCY = WARN;
    step 2: 每台server执行
    SET @@GLOBAL.ENFORCE_GTID_CONSISTENCY = ON;
    step 3: 每台server执行 > 不用关心一组复制集群的server的执行顺序,只需要保证每个Server都执行了,才能进行下一步
    SET @@GLOBAL.GTID_MODE = OFF_PERMISSIVE;
    step 4: 每台server执行 > 不用关心一组复制集群的server的执行顺序,只需要保证每个Server都执行了,才能进行下一步
    SET @@GLOBAL.GTID_MODE = ON_PERMISSIVE;
    step 5: 在每台server上执行,如果ONGOING_ANONYMOUS_TRANSACTION_COUNT=0就可以 > 不需要一直为0,只要出现过0一次,就ok
    SHOW STATUS LIKE 'ONGOING_ANONYMOUS_TRANSACTION_COUNT';
    step 6: 确保所有anonymous事务传递到slave上了
    1. master
    SHOW MASTER STATUS;
    2. 每个slave
    SELECT MASTER_POS_WAIT(file, position);
    或者,等一段时间,只要不是大的延迟,一般都没问题
    step 7: 每台Server上执行
    SET @@GLOBAL.GTID_MODE = ON;
    step 8: 在每台server上将my.cnf中添加好gtid配置
    gtid_mode=ON(必选)
    enforce-gtid-consistency(必选)
    log_bin=ON(可选)--高可用切换,最好设置ON
    log-slave-updates=ON(可选)--高可用切换,最好设置ON
    step 9: change master
    STOP SLAVE;
    CHANGE MASTER TO MASTER_AUTO_POSITION = 1;
    START SLAVE;
    • GTID failover

           1) MySQL crash

           配置好loss-less semi-sync replication,可以更可靠的保证数据零丢失。
    以下说的都是crash 后,起不来的情况:

           binlog 在master还有日志没有传递到 slave
              1. 选取最新的slave,change master to maseter_auto_position同步好
              2. mysqlbinlog 将没传递过来的binlog在新master上replay
              3. 打开新master的surper_read_only=off;
           binlog 已经传递到slave
              1. 选取最新的slave,change master to maseter_auto_position同步好
              2. 打开新master的surper_read_only=off;
          2) OS crash

              1. 选取最新的slave,change master to maseter_auto_position同步好
              2. 打开新master的surper_read_only=off;
    以上操作,在传统模式复制下,只能通过MHA来实现,MHA比较复杂。现在,在GTID模式下,实现起来非常简单,且非常方便。

    • Slave skip gtid

          1) 传统模式

    * skip transation;
    SQL> SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1;
    SQL> START SLAVE;

          2) GTID模式

    SQL> SET GTID_NEXT='b9b4712a-df64-11e3-b391-60672090eb04:7'; --设置需要跳过的gtid event
    SQL> BEGIN;COMMIT;
    SQL> SET GTID_NEXT='AUTOMATIC';
    SQL> START SLAVE;

           对于第二种不小心多执行了事务:

           这种情况就比较难了,这样已经导致了数据不一致,大多数情况,建议slave重做
           如何避免: slave 设置 super_read_only=on

    • 故障模拟:slave所需要事务对应的GTID在master上已经被purge了,忽略purged的部分,强行同步
    master节点执行:
    master [localhost] {msandbox} (test) > show global variables like '%gtid%';
    +---------------------------------+----------------------------------------+
    | Variable_name                   | Value                                  |
    +---------------------------------+----------------------------------------+
    | binlog_gtid_simple_recovery     | OFF                                    |
    | enforce_gtid_consistency        | ON                                     |
    | gtid_executed                   | 24024e52-bd95-11e4-9c6d-926853670d0b:1 |
    | gtid_mode                       | ON                                     |
    | gtid_owned                      |                                        |
    | gtid_purged                     |                                        |
    | simplified_binlog_gtid_recovery | OFF                                    |
    +---------------------------------+----------------------------------------+
    7 rows in set (0.01 sec)
    master [localhost] {msandbox} (test) > flush logs;create table gtid_test2 (ID int) engine=innodb;
    Query OK, 0 rows affected (0.04 sec)
    Query OK, 0 rows affected (0.02 sec)
    master [localhost] {msandbox} (test) > flush logs;create table gtid_test3 (ID int) engine=innodb;
    Query OK, 0 rows affected (0.04 sec)
    Query OK, 0 rows affected (0.04 sec)
    master [localhost] {msandbox} (test) > show master status;
    +------------------+----------+--------------+------------------+------------------------------------------+
    | File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set                        |
    +------------------+----------+--------------+------------------+------------------------------------------+
    | mysql-bin.000005 |      359 |              |                  | 24024e52-bd95-11e4-9c6d-926853670d0b:1-3 |
    +------------------+----------+--------------+------------------+------------------------------------------+
    1 row in set (0.00 sec)
    master [localhost] {msandbox} (test) > purge binary logs to 'mysql-bin.000004';
    Query OK, 0 rows affected (0.03 sec)
    master [localhost] {msandbox} (test) > show global variables like '%gtid%';
    +---------------------------------+------------------------------------------+
    | Variable_name                   | Value                                    |
    +---------------------------------+------------------------------------------+
    | binlog_gtid_simple_recovery     | OFF                                      |
    | enforce_gtid_consistency        | ON                                       |
    | gtid_executed                   | 24024e52-bd95-11e4-9c6d-926853670d0b:1-3 |
    | gtid_mode                       | ON                                       |
    | gtid_owned                      |                                          |
    | gtid_purged                     | 24024e52-bd95-11e4-9c6d-926853670d0b:1   |
    | simplified_binlog_gtid_recovery | OFF                                      |
    +---------------------------------+------------------------------------------+
    7 rows in set (0.00 sec)
    在slave2上重新做一次主从,以下命令在slave2上执行
    slave2 [localhost] {msandbox} ((none)) > change master to master_host='127.0.0.1',master_port =21288,master_user='rsandbox',master_password='rsandbox',master_auto_position=1;
    Query OK, 0 rows affected, 2 warnings (0.04 sec)
    slave2 [localhost] {msandbox} ((none)) > start slave;
    Query OK, 0 rows affected (0.01 sec)
    slave2 [localhost] {msandbox} ((none)) > show slave statusG
    *************************** 1. row ***************************
                              ......
                 Slave_IO_Running: No
                Slave_SQL_Running: Yes
                              ......
                       Last_Errno: 0
                       Last_Error:
                     Skip_Counter: 0
              Exec_Master_Log_Pos: 0
                  Relay_Log_Space: 151
                              ......
                    Last_IO_Errno: 1236
                    Last_IO_Error: Got fatal error 1236 from master when reading data from binary log: 'The slave is connecting using CHANGE MASTER TO MASTER_AUTO_POSITION = 1, but the master has purged binary logs containing GTIDs that the slave requires.'
                   Last_SQL_Errno: 0
                   Last_SQL_Error:
                              ......
                    Auto_Position: 1
    1 row in set (0.00 sec)
    

        忽略purged的部分,强行同步

           先确认master上已经purge的部分。从下面的命令结果可以知道master上已经缺失24024e52-bd95-11e4-9c6d-926853670d0b:1这一条事务的相关日志,在slave上通过set global gtid_purged='xxxx'的方式,跳过已经purge的部分 

    master [localhost] {msandbox} (test) > show global variables like '%gtid%';
    +---------------------------------+------------------------------------------+
    | Variable_name                   | Value                                    |
    +---------------------------------+------------------------------------------+
    | binlog_gtid_simple_recovery     | OFF                                      |
    | enforce_gtid_consistency        | ON                                       |
    | gtid_executed                   | 24024e52-bd95-11e4-9c6d-926853670d0b:1-3 |
    | gtid_mode                       | ON                                       |
    | gtid_owned                      |                                          |
    | gtid_purged                     | 24024e52-bd95-11e4-9c6d-926853670d0b:1   |
    | simplified_binlog_gtid_recovery | OFF                                      |
    +---------------------------------+------------------------------------------+
    7 rows in set (0.00 sec)
    
    slave2 [localhost] {msandbox} ((none)) > stop slave;
    Query OK, 0 rows affected (0.04 sec)
    slave2 [localhost] {msandbox} ((none)) > set global gtid_purged = '24024e52-bd95-11e4-9c6d-926853670d0b:1';
    Query OK, 0 rows affected (0.05 sec)
    slave2 [localhost] {msandbox} ((none)) > start slave;
    Query OK, 0 rows affected (0.01 sec)
    slave2 [localhost] {msandbox} ((none)) > show slave statusG                
    *************************** 1. row ***************************
                   Slave_IO_State: Waiting for master to send event
                              ......
                  Master_Log_File: mysql-bin.000005
              Read_Master_Log_Pos: 359
                   Relay_Log_File: mysql_sandbox21290-relay-bin.000004
                    Relay_Log_Pos: 569
            Relay_Master_Log_File: mysql-bin.000005
                 Slave_IO_Running: Yes
                Slave_SQL_Running: Yes
                              ......
              Exec_Master_Log_Pos: 359
                  Relay_Log_Space: 873
                              ......
                 Master_Server_Id: 1
                      Master_UUID: 24024e52-bd95-11e4-9c6d-926853670d0b
                 Master_Info_File: /data/mysql/rsandbox_mysql-5_6_23/node2/data/master.info
                        SQL_Delay: 0
              SQL_Remaining_Delay: NULL
          Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it
                              ......
               Retrieved_Gtid_Set: 24024e52-bd95-11e4-9c6d-926853670d0b:2-3
                Executed_Gtid_Set: 24024e52-bd95-11e4-9c6d-926853670d0b:1-3
                    Auto_Position: 1
    1 row in set (0.00 sec)
    

       此时slave已经可以正常同步,并补齐了24024e52-bd95-11e4-9c6d-926853670d0b:2-3范围的binlog日志

    • QA

    1)  如何重置gtid_executed,gtid_purged
    设置gtid_executed
    目前只能够reset master
    设置gtid_purged
    * 当gtid_executed 非空的时候,不能设置gtid_purged
    * 当gtid_executed 为空的时候(即刚刚备份好的镜像,刚搭建的mysql),可以直接SET @@GLOBAL.GTID_PURGED='0ad6eae9-2d66-11e6-864f-ecf4bbf1f42c:1-3';

    2)  如果auto.cnf 被删掉了,对于GTID的复制会有什么影响?
    如果被删掉,重启后,server-uuid 会变

    3)  手动设置 set @@gtid_purged = xx:yy, mysql会去主动修改binlog的头么
    不会

    4)  GTID和复制过滤规则之间如何协同工作?MySQL,test还能愉快的过滤掉吗?
    可以,该过滤的会自己过滤,不用担心

     

  • 相关阅读:
    安全性测试的测试点
    Python基础,,小题目
    Python画小猪佩奇
    Python代码
    Python画圆
    python编写贪吃蛇游戏
    主键、外键的作用,索引的优点与不足
    LoadRunner分为哪三个模块?请简述各模块的主要功能。
    测试结束的标准
    坚持“5W”规则,明确内容与过程
  • 原文地址:https://www.cnblogs.com/vadim/p/7405237.html
Copyright © 2011-2022 走看看