阅读681 返回首页    go 阿里云 go 技术社区[云栖]


GTID跳过单个、多个事务的方法

[toc]

1、概述

使用gtid跳过事务有两种方法:
1. set gtid_next,可以跳过单个事务
2. set GTID_PURGED,可以跳过多个事务

2、跳过单个事物

情景:

主新建了test.t1 表,从误操作删掉了test.t1;
主往test.t1中插入一条数据,从库报错
  • 主:

    mysql> begin;
    mysql> insert into test.t1 values (1,1);
    mysql> commit;
    mysql> show master status \G
    *************************** 1. row ***************************
            File: mysql-bin.000002
        Position: 3286
    Binlog_Do_DB: 
    Binlog_Ignore_DB: 
    Executed_Gtid_Set: 59fe7a3e-9dd6-11e7-9d6c-000c29e57c69:1-17
    1 row in set (0.00 sec)
    
  • 从:

    mysql> show slave status \G
    *************************** 1. row ***************************
              Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.234.130
                  Master_User: repl
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000002
          Read_Master_Log_Pos: 3286
              Relay_Log_File: ser2-relay-bin.000006
                Relay_Log_Pos: 1141
        Relay_Master_Log_File: mysql-bin.000002
            Slave_IO_Running: Yes
            Slave_SQL_Running: No
              Replicate_Do_DB:
          Replicate_Ignore_DB:
          Replicate_Do_Table:
      Replicate_Ignore_Table:
      Replicate_Wild_Do_Table:
    Replicate_Wild_Ignore_Table:
                  Last_Errno: 1146
                  Last_Error: Worker 3 failed executing transaction '59fe7a3e-9dd6-11e7-9d6c-000c29e57c69:17' at master log mysql-bin.000002, end_log_pos 3255; Error executing row event: 'Table 'test.t1' doesn't exist'
                Skip_Counter: 0
          Exec_Master_Log_Pos: 3045
              Relay_Log_Space: 2699
              Until_Condition: None
              Until_Log_File:
                Until_Log_Pos: 0
          Master_SSL_Allowed: No
          Master_SSL_CA_File:
          Master_SSL_CA_Path:
              Master_SSL_Cert:
            Master_SSL_Cipher:
              Master_SSL_Key:
        Seconds_Behind_Master: NULL
    Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error:
              Last_SQL_Errno: 1146
              Last_SQL_Error: Worker 3 failed executing transaction '59fe7a3e-9dd6-11e7-9d6c-000c29e57c69:17' at master log mysql-bin.000002, end_log_pos 3255; Error executing row event: 'Table 'test.t1' doesn't exist'
    Replicate_Ignore_Server_Ids:
            Master_Server_Id: 1
                  Master_UUID: 59fe7a3e-9dd6-11e7-9d6c-000c29e57c69
            Master_Info_File: mysql.slave_master_info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State:
          Master_Retry_Count: 86400
                  Master_Bind:
      Last_IO_Error_Timestamp:
    Last_SQL_Error_Timestamp: 170922 00:30:21
              Master_SSL_Crl:
          Master_SSL_Crlpath:
          Retrieved_Gtid_Set: 59fe7a3e-9dd6-11e7-9d6c-000c29e57c69:1-17
            Executed_Gtid_Set: 29bd8c99-9e4d-11e7-a072-000c29d00b2d:1,
    59fe7a3e-9dd6-11e7-9d6c-000c29e57c69:1-16
                Auto_Position: 1
    1 row in set (0.00 sec)
    

通过查看我们得知:
从库在执行59fe7a3e-9dd6-11e7-9d6c-000c29e57c69:17 这个事务时,因为从库没有这个表而报错了。

2. 解决思路:

  1. root用户手动重建test.t1表
  2. root用户手动在59fe7a3e-9dd6-11e7-9d6c-000c29e57c69:17 这个事务上执行一个空事务

3. 解决步骤:

  • 在从库上重建 test.t1 表

    主库备份
    # mysqldump -uroot -p123123  -h127.0.0.1  --single-transaction --set-gtid-purged=off  --triggers --routines --events  test t1 >/tmp/t1.sql
    从库恢复
    # cat t1.sql |mysql -uroot -p123123 test
    
  • 从库在冲突事务号执行空事务

    > stop slave;
    > SET @@SESSION.GTID_NEXT= '59fe7a3e-9dd6-11e7-9d6c-000c29e57c69:17'/*!*/;
    > show variables like '%gtid%_next';
    > BEGIN;COMMIT;
    > SET gtid_next = 'AUTOMATIC';
    > START SLAVE;
    

3、批量跳过

1. 情景模拟

由于数据不一致严重,跳过单个事务不能继续正常复制。
从库删掉单表,然后跳过批量sql,继续复制

  • 从:

    mysql> truncate table test.t1;
    
  • 主:

    mysql>
    mysql> begin;
    mysql> update test.t1 set age=11 where id=1;        //如果只跳过这个事务,下个事务还是会出错
    mysql> commit;
    mysql> begin;
    mysql> update test.t1 set age=33 where id=3;
    mysql> commit;
    

2. 操作步骤

  • 主库备份表
    set-gtid-purged ==> SQL_LOG_BIN= 0、SET @@GLOBAL.GTID_PURGED

    # mysqldump -uroot -p123123  -h127.0.0.1  --single-transaction --set-gtid-purged=on  --triggers --routines --events  test t1 >/tmp/t1.sql
    # cat /tmp/t1.sql |egrep SET |egrep -v "^/"
    SET @MYSQLDUMP_TEMP_LOG_BIN = @@SESSION.SQL_LOG_BIN;
    SET @@SESSION.SQL_LOG_BIN= 0;
    SET @@GLOBAL.GTID_PURGED='59fe7a3e-9dd6-11e7-9d6c-000c29e57c69:1-22';
    ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
    SET @@SESSION.SQL_LOG_BIN = @MYSQLDUMP_TEMP_LOG_BIN;
    
  • 从库恢复

    > reset master;        //清空GTID_EXECUTED 
    # cat t1.sql |mysql -uroot -p123123 test
    会执行备份文件中的SET @@GLOBAL.GTID_PURGED。 @@GLOBAL.GTID_PURGED can only be set when @@GLOBAL.GTID_EXECUTED is empty.
    > show slave status \G
          Retrieved_Gtid_Set: 59fe7a3e-9dd6-11e7-9d6c-000c29e57c69:1-22
          Executed_Gtid_Set: 59fe7a3e-9dd6-11e7-9d6c-000c29e57c69:1-22
    > start slave;
    

最后更新:2017-09-27 09:33:09

  上一篇:go  2017杭州·云栖大会---大数据workshop:《云数据·大计算:海量日志数据分析与应用》之《数据采集:日志数据上传》篇
  下一篇:go  喜讯!RocketMQ成为Apache软件基金会顶级开源项目