In order to ensure that no other parameter configuration is affected, a minimally installed CentOS7 virtual machine is reinstalled and configured
1. Basic knowledge
Install mysql5.6 database https://my.oschina.net/sgmder/blog/1631045
Mysql binlog preliminary understanding https://my.oschina.net/sgmder/blog/1631432
2. Configure mysql, enable binlog, and modify binlog mode to Row Level mode
vi /etc/my.cnf
Modify the mysql configuration file and add the following under [mysqld]
# 注释: 开启binlog 文件名以mysql-bin开头
log-bin = mysql-bin
# 注释: 备份恢复模式不需要开启Row模式 闪回需要开启Row模式
binlog_format="ROW"
Restart the mysql database binlog to open the generated file /var/lib/mysql/mysql-bin.000001
service mysqld restart
Log in to the database and create a test database demo and test table user
mysql> create database demo;
Query OK, 1 row affected (0.00 sec)
mysql> use demo;
Database changed
mysql> CREATE TABLE `user` ( `id` int(8) NOT NULL AUTO_INCREMENT, `name` varchar(32) NOT NULL, `type` int(8) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB;
Query OK, 0 rows affected (0.01 sec)
After the preparation is complete, refresh the binlog file. At this time, the binlog file mysql-bin.000001 ends and enters the mysql-bin.000002 record.
mysql> flush logs;
Query OK, 0 rows affected (0.00 sec)
backup database
[root@localhost ~]# mysqldump -u root -p --databases demo > db_demo_bak.sql
3. Use backup + binlog record to roll back the database
Enter the database and insert 2 test data first
mysql> insert into user (id,name,type) value (10001,'A','1');
Query OK, 1 row affected (0.00 sec)
mysql> insert into user (id,name,type) value (10002,'B','1');
Query OK, 1 row affected (0.00 sec)
View data
mysql> select * from user;
+-------+------+------+
| id | name | type |
+-------+------+------+
| 10001 | A | 1 |
| 10002 | B | 1 |
+-------+------+------+
2 rows in set (0.00 sec)
Simulate misoperation update to modify database data
mysql> update user set name = 'C';
Query OK, 2 rows affected (0.00 sec)
Rows matched: 2 Changed: 2 Warnings: 0
mysql> select * from user;
+-------+------+------+
| id | name | type |
+-------+------+------+
| 10001 | C | 1 |
| 10002 | C | 1 |
+-------+------+------+
2 rows in set (0.00 sec)
The name field of the user table has been modified by misoperation. Quickly refresh the binlog file, mysql-bin.000002 ends, and subsequent operations enter mysql-bin.000003
mysql> flush logs;
Query OK, 0 rows affected (0.01 sec)
At this point, look at the mysql binlog file
[root@localhost ~]# ls /var/lib/mysql
auto.cnf ibdata1 ib_logfile1 mysql-bin.000001 mysql-bin.000003 mysql.sock
demo ib_logfile0 mysql mysql-bin.000002 mysql-bin.index performance_schema
Then, the mysql-bin.000002 file records all database executions from backup to misoperation. Now we need to restore the data that was misoperated by update.
First use the backup to restore the database. At this time, the table user has no data
mysql> user demo;
mysql> drop table user;
mysql> source /root/db_demo_bak.sql
mysql> select * from user;
Empty set (0.00 sec)
View the operations recorded by mysql-bin.000002, and view the Pos and End_log_pos of each operation
mysql> show binlog events in 'mysql-bin.000002';
+------------------+-----+-------------+-----------+-------------+---------------------------------------+
| Log_name | Pos | Event_type | Server_id | End_log_pos | Info |
+------------------+-----+-------------+-----------+-------------+---------------------------------------+
| mysql-bin.000002 | 4 | Format_desc | 1 | 120 | Server ver: 5.6.39-log, Binlog ver: 4 |
| mysql-bin.000002 | 120 | Query | 1 | 192 | BEGIN |
| mysql-bin.000002 | 192 | Table_map | 1 | 243 | table_id: 72 (demo.user) |
| mysql-bin.000002 | 243 | Write_rows | 1 | 289 | table_id: 72 flags: STMT_END_F |
| mysql-bin.000002 | 289 | Xid | 1 | 320 | COMMIT /* xid=147 */ |
| mysql-bin.000002 | 320 | Query | 1 | 392 | BEGIN |
| mysql-bin.000002 | 392 | Table_map | 1 | 443 | table_id: 72 (demo.user) |
| mysql-bin.000002 | 443 | Write_rows | 1 | 489 | table_id: 72 flags: STMT_END_F |
| mysql-bin.000002 | 489 | Xid | 1 | 520 | COMMIT /* xid=148 */ |
| mysql-bin.000002 | 520 | Query | 1 | 592 | BEGIN |
| mysql-bin.000002 | 592 | Table_map | 1 | 643 | table_id: 72 (demo.user) |
| mysql-bin.000002 | 643 | Update_rows | 1 | 723 | table_id: 72 flags: STMT_END_F |
| mysql-bin.000002 | 723 | Xid | 1 | 754 | COMMIT /* xid=149 */ |
| mysql-bin.000002 | 754 | Rotate | 1 | 801 | mysql-bin.000003;pos=4 |
+------------------+-----+-------------+-----------+-------------+---------------------------------------+
14 rows in set (0.00 sec)
120 - 320 first insert
320 - 520 second insert
520 - 754 Misoperation update
Use the mysqlbinlog tool to restore insert operations 120 - 520
[root@localhost ~]# mysqlbinlog --start-position=120 --stop-position=520 --database=demo /var/lib/mysql/mysql-bin.000003 | /usr/bin/mysql -u root -p mima666 -v demo
For the detailed usage of mysqlbinlog, please refer to the official documentation https://dev.mysql.com/doc/refman/5.6/en/mysqlbinlog.html
View the user table data
mysql> select * from user;
+-------+------+------+
| id | name | type |
+-------+------+------+
| 10001 | A | 1 |
| 10002 | B | 1 |
+-------+------+------+
2 rows in set (0.00 sec)
Ok, data recovery is successful
4. Use binlog+MyFlash to roll back the database
Refer to Meituan's open source project MyFlash