一、binlog-rollback.pl工具介绍

是perl开发的脚本工具,此工具主要是生成反向的DML sql语句:

#基于row模式的binlog,生成DML(insert/update/delete)的rollback语句

#通过mysqlbinlog -v 解析binlog生成可读的sql文件

#提取需要处理的有效sql

#"### "开头的行.如果输入的start-position位于某个event group中间,则会导致"无法识别event"错误

#将INSERT/UPDATE/DELETE 的sql反转,并且1个完整sql只能占1行

#INSERT: INSERT INTO => DELETE FROM, SET => WHERE

#UPDATE: WHERE => SET, SET => WHERE

#DELETE: DELETE FROM => INSERT INTO, WHERE => SET

#用列名替换位置@{1,2,3}

#通过desc table获得列顺序及对应的列名

#特殊列类型value做特别处理

#逆序

#注意:

#表结构与现在的表结构必须相同[谨记]

#由于row模式是幂等的,并且恢复是一次性,所以只提取sql,不提取BEGIN/COMMIT

#只能对INSERT/UPDATE/DELETE进行处理

#线上误操作后,一定要立刻对操作的表进行加锁,避免其他数据继续写入

二、MySQL server必须设置以下参数:

MySQL的版本是mysql5.6.36

cat /etc/my.cnf

[client]

port = 3306

socket = /tmp/mysql.sock

default-character-set=utf8

[mysqld]

server_id = 1

log_bin = /var/log/mysql/mysql-bin

max_binlog_size = 1G

binlog_format = row

binlog_row_image = full

character-set-server = utf8

三、此工具使用需要创建一个mysql的管理用户来操作

不建议直接使用mysql的root账户来操作,建议授权一个最小权限的用户来操作

登录mysql创建最小的授权用户admin

user需要的最小权限集合:

select, super/replication client, replication slave

GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO

权限说明

select:需要读取server端information_schema.COLUMNS表,获取表结构的元信息,拼接成可视化的sql语句

super/replication client:两个权限都可以,需要执行'SHOW MASTER STATUS', 获取server端的binlog列表

replication slave:通过BINLOG_DUMP协议获取binlog内容的权限

MySQL [(none)]> GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO admin@'127.0.0.1' identified by 'admin';

四、binlog-rollback.pl工具参数介绍

[root@git-server opt]# perl binlog-rollback.pl -help

:please input binlog file

==========================================================================================

Command line options :

--help # OUT : print help info

-f, --srcfile # IN : binlog file. [required]

-o, --outfile # OUT : output sql file. [required]

-h, --host # IN : host. default '127.0.0.1'

-u, --user # IN : user. [required]

-p, --password # IN : password. [required]

-P, --port # IN : port. default '3306'

--start-datetime # IN : start datetime

--stop-datetime # IN : stop datetime

--start-position # IN : start position

--stop-position # IN : stop position

-d, --database # IN : database, split comma

-T, --table # IN : table, split comma. [required] set -d

-i, --ignore # IN : ignore binlog check contain DDL(CREATE|ALTER|DROP|RENAME)

--debug # IN : print debug information

Sample :

shell> perl binlog-rollback.pl -f 'mysql-bin.000001' -o '/tmp/t.sql' -u 'user' -p 'pwd'

shell> perl binlog-rollback.pl -f 'mysql-bin.000001' -o '/tmp/t.sql' -u 'user' -p 'pwd' -i

shell> perl binlog-rollback.pl -f 'mysql-bin.000001' -o '/tmp/t.sql' -u 'user' -p 'pwd' --debug

shell> perl binlog-rollback.pl -f 'mysql-bin.000001' -o '/tmp/t.sql' -h '192.168.1.2' -u 'user' -p 'pwd' -P 3307

shell> perl binlog-rollback.pl -f 'mysql-bin.000001' -o '/tmp/t.sql' -u 'user' -p 'pwd' --start-position=107

shell> perl binlog-rollback.pl -f 'mysql-bin.000001' -o '/tmp/t.sql' -u 'user' -p 'pwd' --start-position=107 --stop-position=10000

shell> perl binlog-rollback.pl -f 'mysql-bin.000001' -o '/tmp/t.sql' -u 'user' -p 'pwd' -d 'db1,db2'

shell> perl binlog-rollback.pl -f 'mysql-bin.0000*' -o '/tmp/t.sql' -u 'user' -p 'pwd' -d 'db1,db2' -T 'tb1,tb2'

操作报错如下:

[root@git-server opt]# perl binlog-rollback.pl -f '/data/mysql/data/mysql-bin.000002' -o '/tmp/t.sql' -u 'admin' -p 'admin'

mysqlbinlog: unknown variable 'default-character-set=utf8'

mysqlbinlog: unknown variable 'default-character-set=utf8'

mysqlbinlog: unknown variable 'default-character-set=utf8'

解决办法:

[root@git-server opt]# grep mysqlbinlog binlog-rollback.pl

#通过mysqlbinlog -v 解析binlog生成可读的sql文件

$MYSQLBINLOG = qq{mysqlbinlog --no-defaults -v}; ###添加上参数--no-defaults 解决问题

五、测试delete,和update误操作后的sql语提取和数据的恢复

5.1delete删除忘记添加条件恢复测试

MySQL [zixun3]> select * from zx_scores;

+----+--------+------+----------+-----------+

| id | titles | icon | integral | isdefault |

+----+--------+------+----------+-----------+

| 2 | 列兵 | 1 | 0 | 1 |

| 3 | 班长 | 2 | 1000 | 1 |

| 4 | 少尉 | 3 | 2000 | 1 |

| 5 | 中尉 | 4 | 3000 | 1 |

| 6 | 上尉 | 5 | 4000 | 1 |

| 7 | 少校 | 6 | 5000 | 1 |

| 8 | 中校 | 7 | 6000 | 1 |

| 9 | 上校 | 8 | 9000 | 1 |

| 10 | 少将 | 9 | 14000 | 1 |

| 11 | 中将 | 10 | 19000 | 1 |

| 12 | 上将 | 11 | 24000 | 1 |

| 15 | 大将 | 12 | 29000 | 1 |

+----+--------+------+----------+-----------+

12 rows in set (0.00 sec)

MySQL [zixun3]> show master status\G

*************************** 1. row ***************************

File: mysql-bin.000003

Position: 592

Binlog_Do_DB:

Binlog_Ignore_DB:

Executed_Gtid_Set:

1 row in set (0.00 sec)

MySQL [zixun3]> flush logs;

Query OK, 0 rows affected (0.10 sec)

MySQL [zixun3]> show master status\G

*************************** 1. row ***************************

File: mysql-bin.000004

Position: 120

Binlog_Do_DB:

Binlog_Ignore_DB:

Executed_Gtid_Set:

1 row in set (0.00 sec)

delete删除时,不加任何条件,导致误删除

MySQL [zixun3]> delete from zx_scores;

Query OK, 12 rows affected (0.00 sec)

MySQL [zixun3]>

[root@git-server opt]# perl binlog-rollback.pl -f '/data/mysql/data/mysql-bin.000004' -o '/tmp/insert.sql' -u 'admin' -p 'admin' -h 127.0.0.1 -i

Warning: Using a password on the command line interface can be insecure.

[root@git-server opt]# cat /tmp/insert.sql

INSERT INTO `zixun3`.`zx_scores` SET `id`=15, `titles`='大将', `icon`=12, `integral`=29000, `isdefault`=1;

INSERT INTO `zixun3`.`zx_scores` SET `id`=12, `titles`='上将', `icon`=11, `integral`=24000, `isdefault`=1;

INSERT INTO `zixun3`.`zx_scores` SET `id`=11, `titles`='中将', `icon`=10, `integral`=19000, `isdefault`=1;

INSERT INTO `zixun3`.`zx_scores` SET `id`=10, `titles`='少将', `icon`=9, `integral`=14000, `isdefault`=1;

INSERT INTO `zixun3`.`zx_scores` SET `id`=9, `titles`='上校', `icon`=8, `integral`=9000, `isdefault`=1;

INSERT INTO `zixun3`.`zx_scores` SET `id`=8, `titles`='中校', `icon`=7, `integral`=6000, `isdefault`=1;

INSERT INTO `zixun3`.`zx_scores` SET `id`=7, `titles`='少校', `icon`=6, `integral`=5000, `isdefault`=1;

INSERT INTO `zixun3`.`zx_scores` SET `id`=6, `titles`='上尉', `icon`=5, `integral`=4000, `isdefault`=1;

INSERT INTO `zixun3`.`zx_scores` SET `id`=5, `titles`='中尉', `icon`=4, `integral`=3000, `isdefault`=1;

INSERT INTO `zixun3`.`zx_scores` SET `id`=4, `titles`='少尉', `icon`=3, `integral`=2000, `isdefault`=1;

INSERT INTO `zixun3`.`zx_scores` SET `id`=3, `titles`='班长', `icon`=2, `integral`=1000, `isdefault`=1;

INSERT INTO `zixun3`.`zx_scores` SET `id`=2, `titles`='列兵', `icon`=1, `integral`=0, `isdefault`=1;

MySQL [zixun3]> source /tmp/insert.sql

MySQL [zixun3]> select * from zx_scores;

+----+--------+------+----------+-----------+

| id | titles | icon | integral | isdefault |

+----+--------+------+----------+-----------+

| 2 | 列兵 | 1 | 0 | 1 |

| 3 | 班长 | 2 | 1000 | 1 |

| 4 | 少尉 | 3 | 2000 | 1 |

| 5 | 中尉 | 4 | 3000 | 1 |

| 6 | 上尉 | 5 | 4000 | 1 |

| 7 | 少校 | 6 | 5000 | 1 |

| 8 | 中校 | 7 | 6000 | 1 |

| 9 | 上校 | 8 | 9000 | 1 |

| 10 | 少将 | 9 | 14000 | 1 |

| 11 | 中将 | 10 | 19000 | 1 |

| 12 | 上将 | 11 | 24000 | 1 |

| 15 | 大将 | 12 | 29000 | 1 |

+----+--------+------+----------+-----------+

12 rows in set (0.00 sec)

delete操作恢复完成

5.2update更新时忘记加条件限制的数据恢复

MySQL [zixun3]> update zx_scores set titles='班长';

Query OK, 11 rows affected (0.00 sec)

Rows matched: 12 Changed: 11 Warnings: 0

MySQL [zixun3]> select * from zx_scores;

+----+--------+------+----------+-----------+

| id | titles | icon | integral | isdefault |

+----+--------+------+----------+-----------+

| 2 | 班长 | 1 | 0 | 1 |

| 3 | 班长 | 2 | 1000 | 1 |

| 4 | 班长 | 3 | 2000 | 1 |

| 5 | 班长 | 4 | 3000 | 1 |

| 6 | 班长 | 5 | 4000 | 1 |

| 7 | 班长 | 6 | 5000 | 1 |

| 8 | 班长 | 7 | 6000 | 1 |

| 9 | 班长 | 8 | 9000 | 1 |

| 10 | 班长 | 9 | 14000 | 1 |

| 11 | 班长 | 10 | 19000 | 1 |

| 12 | 班长 | 11 | 24000 | 1 |

| 15 | 班长 | 12 | 29000 | 1 |

+----+--------+------+----------+-----------+

12 rows in set (0.00 sec)

[root@git-server opt]# perl binlog-rollback.pl -f '/data/mysql/data/mysql-bin.000004' -o '/tmp/update.sql' -u 'admin' -p 'admin' -h 127.0.0.1 -i

Warning: Using a password on the command line interface can be insecure.

由于mysql-bin.000004 中记录了所有的sql域名,而且binlog-rollback.pl 次工具是过滤mysql-bin.000004 中所有的DML语句 insert,update,delete,所以需要把单独的update语句过滤出来

[root@git-server opt]# grep -i update /tmp/update.sql >/tmp/3.sql

[root@git-server opt]# cat /tmp/3.sql

UPDATE `zixun3`.`zx_scores` SET `id`=15, `titles`='大将', `icon`=12, `integral`=29000, `isdefault`=1 WHERE `id`=15 AND `titles`='班长' AND `icon`=12 AND `integral`=29000 AND `isdefault`=1;

UPDATE `zixun3`.`zx_scores` SET `id`=12, `titles`='上将', `icon`=11, `integral`=24000, `isdefault`=1 WHERE `id`=12 AND `titles`='班长' AND `icon`=11 AND `integral`=24000 AND `isdefault`=1;

UPDATE `zixun3`.`zx_scores` SET `id`=11, `titles`='中将', `icon`=10, `integral`=19000, `isdefault`=1 WHERE `id`=11 AND `titles`='班长' AND `icon`=10 AND `integral`=19000 AND `isdefault`=1;

UPDATE `zixun3`.`zx_scores` SET `id`=10, `titles`='少将', `icon`=9, `integral`=14000, `isdefault`=1 WHERE `id`=10 AND `titles`='班长' AND `icon`=9 AND `integral`=14000 AND `isdefault`=1;

UPDATE `zixun3`.`zx_scores` SET `id`=9, `titles`='上校', `icon`=8, `integral`=9000, `isdefault`=1 WHERE `id`=9 AND `titles`='班长' AND `icon`=8 AND `integral`=9000 AND `isdefault`=1;

UPDATE `zixun3`.`zx_scores` SET `id`=8, `titles`='中校', `icon`=7, `integral`=6000, `isdefault`=1 WHERE `id`=8 AND `titles`='班长' AND `icon`=7 AND `integral`=6000 AND `isdefault`=1;

UPDATE `zixun3`.`zx_scores` SET `id`=7, `titles`='少校', `icon`=6, `integral`=5000, `isdefault`=1 WHERE `id`=7 AND `titles`='班长' AND `icon`=6 AND `integral`=5000 AND `isdefault`=1;

UPDATE `zixun3`.`zx_scores` SET `id`=6, `titles`='上尉', `icon`=5, `integral`=4000, `isdefault`=1 WHERE `id`=6 AND `titles`='班长' AND `icon`=5 AND `integral`=4000 AND `isdefault`=1;

UPDATE `zixun3`.`zx_scores` SET `id`=5, `titles`='中尉', `icon`=4, `integral`=3000, `isdefault`=1 WHERE `id`=5 AND `titles`='班长' AND `icon`=4 AND `integral`=3000 AND `isdefault`=1;

UPDATE `zixun3`.`zx_scores` SET `id`=4, `titles`='少尉', `icon`=3, `integral`=2000, `isdefault`=1 WHERE `id`=4 AND `titles`='班长' AND `icon`=3 AND `integral`=2000 AND `isdefault`=1;

UPDATE `zixun3`.`zx_scores` SET `id`=2, `titles`='列兵', `icon`=1, `integral`=0, `isdefault`=1 WHERE `id`=2 AND `titles`='班长' AND `icon`=1 AND `integral`=0 AND `isdefault`=1;

MySQL [zixun3]> source //tmp/3.sql ;

MySQL [zixun3]> select * from zx_scores;

+----+--------+------+----------+-----------+

| id | titles | icon | integral | isdefault |

+----+--------+------+----------+-----------+

| 2 | 列兵 | 1 | 0 | 1 |

| 3 | 班长 | 2 | 1000 | 1 |

| 4 | 少尉 | 3 | 2000 | 1 |

| 5 | 中尉 | 4 | 3000 | 1 |

| 6 | 上尉 | 5 | 4000 | 1 |

| 7 | 少校 | 6 | 5000 | 1 |

| 8 | 中校 | 7 | 6000 | 1 |

| 9 | 上校 | 8 | 9000 | 1 |

| 10 | 少将 | 9 | 14000 | 1 |

| 11 | 中将 | 10 | 19000 | 1 |

| 12 | 上将 | 11 | 24000 | 1 |

| 15 | 大将 | 12 | 29000 | 1 |

+----+--------+------+----------+-----------+

12 rows in set (0.00 sec)

完成恢复

简单吧,同时此工具还可以结合位置点和时间点进行恢复,请关注后面的博文。

mysql rollback.pl_binlog-rollback.pl 在线恢复update 和delete不加条件误操作sql相关推荐

  1. mysql 恢复delete操作_MySQL 误操作后数据恢复(update,delete忘加where条件)

    在数据库日常维护中,开发人员是最让人头痛的,很多时候都会由于SQL语句写的有问题导致服务器出问题,导致资源耗尽.最危险的操作就是在做DML操作的时候忘加where条件,导致全表更新,这是作为运维或者D ...

  2. mysql 清除分区数据恢复_MySQL 误操作后数据恢复(update,delete忘加where条件)【转】...

    在数据库日常维护中,开发人员是最让人头痛的,很多时候都会由于SQL语句 写的有问题导致服务器出问题,导致资源耗尽.最危险的操作就是在做DML操作的时候忘加where条件,导致全表更新,这是作为运维或者 ...

  3. mysql数据库数据的删除与恢复

    Part 1 删除数据, truncate 和 delete  的区别 转自:http://blog.is36.com/mysql_difference_of_truncate_and_delete/ ...

  4. update和delete操作忘加where条件导致全表更新的处理方法

    在数据库日常维护中,开发人员是最让人头痛的,很多时候都会由于SQL语句写的有问题导致服务器出问题,导致资源耗尽.最危险的操作就是在做DML操作的时候忘加where条件,导致全表更新,这是作为运维或者D ...

  5. mysql+误操作怎么恢复_MySQL 误操作后如何快速恢复数据

    传统解法 用全量备份重搭实例,再利用增量binlog备份,恢复到误操作之前的状态.然后跳过误操作的SQL,再继续应用binlog.此法费时费力,不值得再推荐. 利用binlog2sql快速闪回 首先, ...

  6. python实现数据库事务回滚_使用Python脚本实现MySQL误操作的快速回滚

    1.简介 在Oracle数据库中,当一个误操作被提交后,我们可以通过Oracle提供的闪回功能将表闪回至误操作之前的状态.mysql中没有原生的flushback功能,DBA误操作时,传统的恢复方式是 ...

  7. MySQL误操作后如何快速恢复数据

    基本上每个跟数据库打交道的程序员(当然也可能是你同事)都会碰一个问题,MySQL误操作后如何快速回滚?比如,delete一张表,忘加限制条件,整张表都没了.假如这还是线上环境核心业务数据,那这事就闹大 ...

  8. SQLServer数据库误操作如何恢复

    总目录 文章目录 总目录 前言 一.恢复数据实例 1.创建初始数据 2.保证数据恢复的前提条件 前提1 - 数据库创建时便已设置恢复模式为完整 前提2 - 至少做过一次完整的备份 3.模拟不小心误操作 ...

  9. mysql rollback to,MySQL存储过程SAVEPOINT ROLLBACK to

    MySQL存储过程SAVEPOINT ROLLBACK to 示例如下: DELIMITER $$ DROP PROCEDURE IF EXISTS `test`.`handlerdemo`$$ CR ...

  10. MySQL增删改查及备份恢复

    数据库创建及增删改查 创建数据库: mysql> create database abc; 连接数据库: mysql> use abc; 创建表: mysql> create tab ...

最新文章

  1. 可能是全网写特征工程最通透的...
  2. oracle文件管理
  3. latex multicolumn_LaTeX入门(3)
  4. 推荐一个在线查看.cer文件的网站
  5. bzoj1015 [JSOI2008]星球大战 并查集
  6. sqlalchemy 过滤
  7. 数据算法可视化学习网站
  8. 设计模式(外观模式)
  9. 「中间件」RocketMQ解决消息顺序和重复性消费问题整理(附测试代码)
  10. 伍德里奇计量经济学导论pdf_伍德里奇 计量经济学导论(第六版) 第3章
  11. 学习笔记12--智能驾驶安全设计案例
  12. 山东法律学校97级二班计算机班,关于表彰全国三好学生、全国优秀学生干部和全国先进班集体及其标兵的决定...
  13. 思考的力量—谈谈程序员成长背后的思考力
  14. 知物由学 | Android 模拟点击研究,如何突围“黑灰产”的自动化作弊?
  15. 云服务器防火墙关闭 tomcat不能正常访问
  16. 如何将pdf转换成txt转换器破解版
  17. 解决adb shell root权限
  18. loj10155 数字转换
  19. LeetCode-108
  20. 《Objective-C高级编程 iOS与OS X多线程和内存管理》读书笔记

热门文章

  1. python小白系列1
  2. golang做php的中间件,Golang 之 中间件
  3. 硬件设计23之三极管开关原理与场效应管开关原理
  4. C实现iBeacon蓝牙测距
  5. 基于Java实现一个简单的记事本Android App
  6. Spark集群环境搭建+Maven、SBT编译部署+IDEA开发(一)
  7. 如何区分前后端bug
  8. 保护眼睛,绿豆沙颜色的RGB值和HSL值
  9. 如何去到Jquery官网下载Jquery
  10. Elastic基本概念