MySQL 5.7 uses delayed replication to restore harmful SQL

In the experiment done a few days ago, the point-in-time recovery and the position-based recovery have the same problem, that is, you need to manually apply all the binlogs one by one (unless you develop a program to automatically apply the binlog), and you need to compare the recovery to the full state. for a long time and may be out of service for a period of time.

If there is a delayed replication standby database, and the problem is discovered before the standby database executes harmful statements, then point-in-time recovery is faster and easier, and there is no need to stop the main database service, only the slave database needs to be restored. After the master-slave switch can be done.

Let's do an experiment:

1. Enable slave replication delay

Mysql (version 5.6 and above) delay replication configuration, which is achieved by setting the MASTER TO MASTER_DELAY parameter on the Slave: 
CHANGE MASTER TO MASTER_DELAY = N; 

N is the number of seconds. This statement sets the slave database to delay for N seconds before synchronously copying data with the master database. 

Set the slave delay to 600 seconds

mysql> stop slave;
Query OK, 0 rows affected (0.03 sec)

mysql> change master to master_delay=600;
Query OK, 0 rows affected (0.01 sec)

mysql> start slave;
Query OK, 0 rows affected (0.01 sec)

mysql> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 172.17.61.131
                  Master_User: repl
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql_bin.000037
          Read_Master_Log_Pos: 154
               Relay_Log_File: slave_relay_bin.000002
                Relay_Log_Pos: 320
        Relay_Master_Log_File: mysql_bin.000037
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
。。。
          Exec_Master_Log_Pos: 154
              Relay_Log_Space: 527
。。。
             Master_Server_Id: 10000
                  Master_UUID: 8d8746fb-2cc6-11e8-b1b6-000c295c63e0
             Master_Info_File: /u01/mysql/master.info
                    SQL_Delay: 600
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
           Master_Retry_Count: 86400
。。。
1 row in set (0.00 sec)

2. Make some changes on the master:

mysql> insert into t1 values(1,'A',11,1);
Query OK, 1 row affected (0.00 sec)

mysql> insert into t1 values(2,'B',22,2);
Query OK, 1 row affected (0.07 sec)

mysql> commit;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from t1;
+------+------+------+----+
| c1   | c2   | c5   | c6 |
+------+------+------+----+
|    1 | A    |   11 |  1 |
|    2 | B    |   22 |  2 |
+------+------+------+----+
2 rows in set (0.00 sec)

3. Execute a harmful sql on the master and delete the table T1 by mistake

mysql> drop table t1;
Query OK, 0 rows affected (0.01 sec)

4. Check the synchronization status on the slave:

mysql> mysql> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 172.17.61.131
                  Master_User: repl
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql_bin.000037
          Read_Master_Log_Pos: 864
               Relay_Log_File: slave_relay_bin.000002
                Relay_Log_Pos: 320
        Relay_Master_Log_File: mysql_bin.000037
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
。。。
                   Last_Errno: 0
                   Last_Error:
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 154
              Relay_Log_Space: 1237
              Until_Condition: None
   。。。
             Master_Server_Id: 10000
                  Master_UUID: 8d8746fb-2cc6-11e8-b1b6-000c295c63e0
             Master_Info_File: /u01/mysql/master.info
                    SQL_Delay: 600
          SQL_Remaining_Delay: 522
      Slave_SQL_Running_State: Waiting until MASTER_DELAY seconds after master executed event
           Master_Retry_Count: 86400
              。。。
1 row in set (0.00 sec)

Slave_SQL_Running_State is waiting for the time set by MASTER_DELAY before synchronizing.

mysql> use l5m;
Database changed
mysql> select * from t1;
Empty set (0.10 sec)

Naturally, the changed data has not been synchronized, and the synchronization of the slave is temporarily stopped.

mysql> stop slave;
Query OK, 0 rows affected (0.00 sec)

At this time, the master database is not affected. If you do some operations on the master, see if the slave can just skip the drop operation and resume the operation on t2.

mysql> insert into t2 values(1,'abc',22,33);
Query OK, 1 row affected (0.00 sec)

mysql> commit;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from t2;
+------+------+------+----+
| c1   | c2   | c3   | c4 |
+------+------+------+----+
|    1 | abc  |   22 | 33 |
+------+------+------+----+
1 row in set (0.00 sec)

5. View the position of the master library drop operation:

[root@qht131 mysql]# mysqlbinlog mysql_bin.000037 | grep -n 'DROP'
73:DROP TABLE `t1` /* generated by server */
[root@qht131 mysql]# mysqlbinlog mysql_bin.000037 | sed -n '60,80p'
nm3YWhMQJwAAMQAAAF0CAAAAAGwAAAAAAAEAA2w1bQACdDEABAMPAwMCHgAHA2kBiA ==
nm3YWh4QJwAAMgAAAI8CAAAAAGwAAAAAAAEAAgAE // ACAAAAAUIWAAAAAgAAAMVZ2os =
'/*!*/;
# at 655
#180419 18:21:18 server id 10000  end_log_pos 686 CRC32 0x19ac01c9      Xid = 33
COMMIT/*!*/;
# at 686
#180419 18:22:11 server id 10000  end_log_pos 751 CRC32 0x04591b0c      Anonymous_GTID  last_committed=2        sequence_number=3       rbr_only=no
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at 751
#180419 18:22:11 server id 10000  end_log_pos 864 CRC32 0xc587394c      Query  thread_id=4      exec_time=0     error_code=0
use `l5m`/*!*/;
SET TIMESTAMP=1524133331/*!*/;
DROP TABLE `t1` /* generated by server */
/*!*/;
SET @@SESSION.GTID_NEXT= 'AUTOMATIC' /* added by mysqlbinlog */ /*!*/;
DELIMITER ;
# End of log file
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;

Viewed through mysqlbinlog, the drop operation occurred in #751 of mysql_bin.000037, and the transaction before #751 was #686

6. Use start slave until on the slave to synchronize the transaction before the drop

mysql> start slave until master_log_file='mysql_bin.000037',master_log_pos=686;
Query OK, 0 rows affected, 1 warning (0.01 sec)

mysql> use l5m
Database changed
mysql> select * from t1;
+------+------+------+----+
| c1   | c2   | c5   | c6 |
+------+------+------+----+
|    1 | A    |   11 |  1 |
|    2 | B    |   22 |  2 |
+------+------+------+----+
2 rows in set (0.00 sec)
mysql> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 172.17.61.131
                  Master_User: repl
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql_bin.000037
          Read_Master_Log_Pos: 864
               Relay_Log_File: slave_relay_bin.000002
                Relay_Log_Pos: 852
        Relay_Master_Log_File: mysql_bin.000037
             Slave_IO_Running: Yes
            Slave_SQL_Running: No
 。。。
          Exec_Master_Log_Pos: 686
              Relay_Log_Space: 1610
              Until_Condition: Master
               Until_Log_File: mysql_bin.000037
                Until_Log_Pos: 686
           Master_SSL_Allowed: No
          。。。
             Master_Server_Id: 10000
                  Master_UUID: 8d8746fb-2cc6-11e8-b1b6-000c295c63e0
             Master_Info_File: /u01/mysql/master.info
                    SQL_Delay: 600
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State:
           Master_Retry_Count: 86400
          。。。
 
 

7. Set sql_slave_skip_counter=1 to adjust the harmful statement, and then reopen the slave replication

mysql> set global sql_slave_skip_counter=1;
Query OK, 0 rows affected (0.01 sec)
mysql> stop slave;
Query OK, 0 rows affected (0.00 sec)

mysql>  change master to master_delay=0;
Query OK, 0 rows affected (0.00 sec)

mysql> start slave;
Query OK, 0 rows affected (0.02 sec)

Before reopening the slave, you need to set master_delay to 0 to synchronize all operations immediately (of course, if there is no harmful SQL that needs to be filtered, all the following binlogs cannot be synchronized immediately).

The data before the drop of the t1 table of the slave library is intact, and the operations after the drop are also synchronized.

mysql> use l5m;
Database changed
mysql> select * from t1;
+------+------+------+----+
| c1   | c2   | c5   | c6 |
+------+------+------+----+
|    1 | A    |   11 |  1 |
|    2 | B    |   22 |  2 |
+------+------+------+----+
2 rows in set (0.00 sec)

mysql> select * from t2;
+------+------+------+----+
| c1   | c2   | c3   | c4 |
+------+------+------+----+
|    1 | abc  |   22 | 33 |
+------+------+------+----+
1 row in set (0.00 sec)

8. The last thing that needs to be done is the master-slave switching operation, which realizes the recovery of harmful SQL without downtime.


Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326725627&siteId=291194637