细心看脚本的朋友都能看到这个脚本需要提供一个连接MySQL的用户,主要是为了获取表结构。下面我们测试一个普通用户并给予SELECT权限即可,默认是host是127.0.0.1,这个可以修改脚本,我这里按脚本默认的:
<Test>[(none)]> GRANT SELECT ON *.* TO 'recovery'@'127.0.0.1' identified by '123456';
Query OK, 0 rows affected (0.08 sec)
<Test>[(none)]> flush privileges;
Query OK, 0 rows affected (0.04 sec)
<Test>[(none)]>
往xuanzhi库的表tb1里插入2行数据,记得binlog格式要为ROW:
<Test>[xuanzhi]> show global variables like 'binlog_format';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| binlog_format | ROW |
+---------------+-------+
1 row in set (0.00 sec)
<Test>[xuanzhi]> insert into xuanzhi.tb1 select 1,'aa';
Query OK, 1 row affected (0.01 sec)
Records: 1 Duplicates: 0 Warnings: 0
<Test>[xuanzhi]> insert into xuanzhi.tb1 select 2,'cc';
Query OK, 1 row affected (0.01 sec)
Records: 1 Duplicates: 0 Warnings: 0
<Test>[xuanzhi]> select * from xuanzhi.tb1;
+------+------+
| id | name |
+------+------+
| 1 | aa |
| 2 | cc |
+------+------+
2 rows in set (0.00 sec)
<Test>[xuanzhi]>
为了看到运行脚本在不指定库看到的效果,我这里再往test库的user表插入两行数据:
<Test>[xuanzhi]> insert into test.user select 1,'user1',20;
Query OK, 1 row affected (0.03 sec)
Records: 1 Duplicates: 0 Warnings: 0
<Test>[xuanzhi]> insert into test.user select 2,'user2',30;
Query OK, 1 row affected (0.01 sec)
Records: 1 Duplicates: 0 Warnings: 0
<Test>[xuanzhi]>
查看此时的此时处于那个binlog:
<Test>[xuanzhi]> show master status;
+----------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------------+----------+--------------+------------------+-------------------+
| localhost-bin.000023 | 936 | | | |
+----------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
<Test>[xuanzhi]>
下面运行脚本 binlog-rollback.pl ,不指定任何库和表的情况下,这时表把binlog里所有DML操作都生成反向的SQL(最新的DML会生成在输入文件的最前面):
[root@localhost mysql3306]# perl binlog-rollback.pl -f 'localhost-bin.000023' -o '/data/t.sql' -u 'recovery' -p '123456'
mysql: [Warning] Using a password on the command line interface can be insecure.
mysql: [Warning] Using a password on the command line interface can be insecure.
[root@localhost mysql3306]#
我们查看输出的文件:/data/t.sql
[root@localhost mysql3306]# cat /data/t.sql
DELETE FROM `test`.`user` WHERE `id`=2 AND `name`='user2' AND `age`=30;
DELETE FROM `test`.`user` WHERE `id`=1 AND `name`='user1' AND `age`=20;
DELETE FROM `xuanzhi`.`tb1` WHERE `id`=2 AND `name`='bb';
DELETE FROM `xuanzhi`.`tb1` WHERE `id`=1 AND `name`='aa';
可以看到,INSERT操作的反向操作就是DELETE,这里把所有库的DML操作都查出来了,在后面会演示找单个库或者表所产生的反向SQL。
下面模拟运维人员、开发人员或者DBA误操删除数据,分别在不同的库删除一条记录:
<Test>[xuanzhi]> delete from xuanzhi.tb1 where id=2;
Query OK, 1 row affected (0.06 sec)
<Test>[xuanzhi]> delete from test.user where id=1;
Query OK, 1 row affected (0.00 sec)
<Test>[xuanzhi]>
这个时候发现自己删除错了,需要恢复,刚好这些数据不在最新的备份里,正常的恢复方法有两种: