• 当 MySQL 出现误操作如 DROP 错表等场景时,基于全备增倍+binlog 补偿恢复可以恢复数据至 DROP 前状态,但使用的时间较长。对于保障级别要求较高的数据库,可以配置延迟从库来缩短恢复数据的时间。
  • 如,可以配置一个晚于 master 30分钟的从库,当 master 发生误操作是,可关闭从库恢复线程,关闭延迟时间,通过 start slave sql_thread until 命令配置执行到 drop 前一个事务停止恢复线程,得到误操作前状态,然后导出并在主库导入,以修正误操作引发的问题。

MySQL 5.7

  • 设置从库接收的事务比主库上的提交至少晚 N 秒才在从库上执行

配置

  • 在已经建立主从复制的情况下
  • 在从库执行
1
2
3
4
stop slave sql_thread;
---- 设置延迟 120 s
CHANGE MASTER TO MASTER_DELAY = 120;
start slave sql_thread;
  • 验证
    • 查看 Seconds_Behind_Master 及 SQL_Delay
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
mysql> show slave status \G
ERROR 2006 (HY000): MySQL server has gone away
No connection. Trying to reconnect...
Connection id:    12889
Current database: *** NONE ***

*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 127.0.0.1
                  Master_User: backup_user
                  Master_Port: 3307
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000002
          Read_Master_Log_Pos: 5747931
               Relay_Log_File: relay-bin.000002
                Relay_Log_Pos: 5698120
        Relay_Master_Log_File: mysql-bin.000002
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB:
          Replicate_Ignore_DB:
           Replicate_Do_Table:
       Replicate_Ignore_Table:
      Replicate_Wild_Do_Table:
  Replicate_Wild_Ignore_Table:
                   Last_Errno: 0
                   Last_Error:
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 5698491
              Relay_Log_Space: 5747761
              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: 119
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error:
               Last_SQL_Errno: 0
               Last_SQL_Error:
  Replicate_Ignore_Server_Ids:
             Master_Server_Id: 13001
                  Master_UUID: b4924d15-db10-11ec-8f08-9c5c8ebe680e
             Master_Info_File: mysql.slave_master_info
			 		------- 配置的 sql 延迟时间 --------
                    SQL_Delay: 120
          SQL_Remaining_Delay: 1
      Slave_SQL_Running_State: Waiting until MASTER_DELAY seconds after master executed event
           Master_Retry_Count: 86400
                  Master_Bind:
      Last_IO_Error_Timestamp:
     Last_SQL_Error_Timestamp:
               Master_SSL_Crl:
           Master_SSL_Crlpath:
           Retrieved_Gtid_Set: b4924d15-db10-11ec-8f08-9c5c8ebe680e:3-13951
            Executed_Gtid_Set: b4924d15-db10-11ec-8f08-9c5c8ebe680e:1-13831
                Auto_Position: 1
         Replicate_Rewrite_DB:
                 Channel_Name:
           Master_TLS_Version:
1 row in set (0.00 sec)

恢复

关闭延迟

1
2
3
stop slave sql_thread;
change master to master_delay=0;
start slave sql_thread;

让 sql_thread 执行到某个时间点停止

  • 执行到指定 log file 和 log pos 停止
    • 执行到指定位置后,sql_thread 会 stop
1
2
3
4
5
-- 关闭 sql_thread 并将延迟更改为 0
stop slave sql_thread;
change master to master_delay=0;
-- 设置 slave sql_thread 执行到 mysql-bin.000002 6256339 前停止
start slave sql_thread until master_log_file='mysql-bin.000002',master_log_pos=6256339;
  • 执行到指定 GTID 位置停止

    • SQL_AFTER_GTIDS:指定 GTID 后
    1
    2
    3
    4
    
    stop slave sql_thread;
    change master to master_delay=0;
    -- 配置执行到 SQL_AFTER_GTIDS,实际执行到的 GTID 为 1-19187
    start slave sql_thread until SQL_AFTER_GTIDS='b4924d15-db10-11ec-8f08-9c5c8ebe680e:1-19187';
    
    • SQL_BEFORE_GTIDS:指定 GTID 前
    1
    2
    3
    4
    
    stop slave sql_thread;
    change master to master_delay=0;
    -- 配置执行到 1-18683 前(语句中无需指定 1-),实际上同步到的位置为 1-18682
    start slave sql_thread until SQL_BEFORE_GTIDS='b4924d15-db10-11ec-8f08-9c5c8ebe680e:18683';