DBA或开发人员,有时会误删或者误更新数据,如果是线上环境并且影响较大,就需要能快速回滚。传统恢复方法是利用备份重搭实例,再应用去除错误sql后的binlog来恢复数据。此法费时费力,甚至需要停机维护,并不适合快速回滚。也有团队利用LVM快照来缩短恢复时间,但快照的缺点是会影响mysql的性能。现在有不少好用而且效率又高的开源闪回工具如binlog2sql、mysqlbinlog_flashback,这些工具在工作中给DBA减轻了不少痛苦,以下针对binlog2sql的使用进行实践演练。

binlog2sql的用途:

  • 数据快速回滚(闪回)
  • 主从切换后数据不一致的修复
  • 从binlog生成标准SQL,带来的衍生功能

安装binlog2sql前先安装git和pip:

yum -y install epel-release 
yum -y install git  python-pip

安装binlog2sql:

git clone https://github.com/danfengcao/binlog2sql.git && cd binlog2sql
pip install -r requirements.txt

MySQL的配置要开启以下选项:

[mysqld]
server_id = 1
log_bin = /var/log/mysql/mysql-bin.log
max_binlog_size = 1G
binlog_format = row
binlog_row_image = full

要授权一个用户有以下权限:

SELECT, REPLICATION SLAVE, REPLICATION CLIENT

权限说明:

  • select:需要读取server端information_schema.COLUMNS表,获取表结构的元信息,拼接成可视化的sql语句
  • super/replication client:两个权限都可以,需要执行'SHOW MASTER STATUS', 获取server端的binlog列表
  • replication slave:通过BINLOG_DUMP协议获取binlog内容的权限

binlog2sql的使用参数说明:

mysql连接配置

-h host; -P port; -u user; -p password

解析模式

--stop-never 持续同步binlog。可选。不加则同步至执行命令时最新的binlog位置。

-K, --no-primary-key 对INSERT语句去除主键。可选。

-B, --flashback 生成回滚语句,可解析大文件,不受内存限制,每打印一千行加一句SLEEP SELECT(1)。可选。与stop-never或no-primary-key不能同时添加。

解析范围控制

--start-file 起始解析文件。必须。

--start-position/--start-pos start-file的起始解析位置。可选。默认为start-file的起始位置。

--stop-file/--end-file 末尾解析文件。可选。默认为start-file同一个文件。若解析模式为stop-never,此选项失效。

--stop-position/--end-pos stop-file的末尾解析位置。可选。默认为stop-file的最末位置;若解析模式为stop-never,此选项失效。

--start-datetime 从哪个时间点的binlog开始解析,格式必须为datetime,如'2016-11-11 11:11:11'。可选。默认不过滤。

--stop-datetime 到哪个时间点的binlog停止解析,格式必须为datetime,如'2016-11-11 11:11:11'。可选。默认不过滤。

对象过滤

-d, --databases 只输出目标db的sql。可选。默认为空。

-t, --tables 只输出目标tables的sql。可选。默认为空。

进行用户授权操作(这里只是举例子):

mysql> GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO  'flashuser'@'127.0.0.1' identified by 'flash123';
Query OK, 0 rows affected (0.00 sec)

我们可以看看现在有的数据:

mysql>  show global variables like 'binlog_format';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| binlog_format | ROW |
+---------------+-------+
1 row in set (0.00 sec) mysql>

mysql> show master status;
+---------------------+----------+--------------+------------------+-------------------------------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+---------------------+----------+--------------+------------------+-------------------------------------------+
| mysql-binlog.000003 | 17724 | | | 8eacaa05-ef11-11e9-89cd-5254007d488a:1-56 |
+---------------------+----------+--------------+------------------+-------------------------------------------+
1 row in set (0.00 sec)

mysql> select * from tb1;

mysql> select * from stu;
+----+----------+
| id | name |
+----+----------+
| 0 | lisi |
| 1 | lili |
| 2 | zhangsan |
+----+----------+
3 rows in set (0.00 sec)

mysql>

我们现在进行数据的DML操作:

mysql> insert into stu values(3, 'wangwu');
Query OK, 1 row affected (0.04 sec)

mysql> insert into stu values(4, 'zhaoliu');
Query OK, 1 row affected (0.03 sec)

mysql> insert into stu values(5, 'xiexun');
Query OK, 1 row affected (0.12 sec)

mysql> insert into stu values(6, 'beifang');
Query OK, 1 row affected (0.03 sec)

mysql> select * from stu;
+----+----------+
| id | name |
+----+----------+
| 0 | lisi |
| 1 | lili |
| 2 | zhangsan |
| 3 | wangwu |
| 4 | zhaoliu |
| 5 | xiexun |
| 6 | beifang |
+----+----------+
7 rows in set (0.00 sec)

mysql>

下面我们使用binlog2sql进行格式为ROW的binlog生成标准SQL,带个-d的参数指定库名:

 
[root@master ~]# python /tmp/binlog2sql/binlog2sql/binlog2sql.py -uglon -h192.168.7.141 -pglon123456 -dtest01 --start-file='mysql-binlog.000003' > test01.sql

[root@master ~]# cat test01.sql

USE test01;
INSERT INTO `test01`.`stu`(`id`, `name`) VALUES (3, 'wangwu'); #start 7253 end 7484 time 2019-10-16 09:46:14
INSERT INTO `test01`.`stu`(`id`, `name`) VALUES (4, 'zhaoliu'); #start 7580 end 7813 time 2019-10-16 09:46:28
INSERT INTO `test01`.`stu`(`id`, `name`) VALUES (5, 'xiexun'); #start 7909 end 8140 time 2019-10-16 09:46:41
INSERT INTO `test01`.`stu`(`id`, `name`) VALUES (6, 'beifang'); #start 8236 end 8469 time 2019-10-16 09:46:52
[root@master ~]#

我们可以看到,刚刚执行过的sql都生成出来了。

我们现在对test01这个库的所有操作生成反向SQL,这个时候需要在上面语句的基础上带一个-B参数,就是flashback闪回的意思:

[root@db_server_xuanzhi ~]#python binlog2sql.py -uflashuser -h127.0.0.1 -pflash123 -dxuanzhi --start-file='mysql-bin.000107' -B  > rollback_xuanzhi.sql

[root@master ~]# python /tmp/binlog2sql/binlog2sql/binlog2sql.py -uglon -h192.168.7.141 -pglon123456 -dtest01 --start-file='mysql-binlog.000003' -B > rollback_test01.sql
[root@master ~]# cat rollback_test01.sql
DELETE FROM `test01`.`stu` WHERE `id`=6 AND `name`='beifang' LIMIT 1; #start 8236 end 8469 time 2019-10-16 09:46:52
DELETE FROM `test01`.`stu` WHERE `id`=5 AND `name`='xiexun' LIMIT 1; #start 7909 end 8140 time 2019-10-16 09:46:41
DELETE FROM `test01`.`stu` WHERE `id`=4 AND `name`='zhaoliu' LIMIT 1; #start 7580 end 7813 time 2019-10-16 09:46:28
DELETE FROM `test01`.`stu` WHERE `id`=3 AND `name`='wangwu' LIMIT 1; #start 7253 end 7484 time 2019-10-16 09:46:14

[root@master ~]#

可以看到生成了跟上面标准SQL相反的SQL了,通过这些反向SQL可以进行误操的数据恢复。

下面我们模拟对线上数据进行误操及恢复的过程:

模拟一:误操把一个表的某些重要记录删除了,进行恢复

我们把tb1的id>=3的数据删除:

mysql> select * from tb1;
+----+------+
| id | name |
+----+------+
| 1 | aa |
| 2 | bb |
| 3 | cc |
| 4 | dd |
+----+------+
4 rows in set (0.00 sec) mysql> delete from tb1 where id >= 3;
Query OK, 2 rows affected (0.00 sec) mysql> select * from tb1;
+----+------+
| id | name |
+----+------+
| 1 | aa |
| 2 | bb |
+----+------+
2 rows in set (0.00 sec) mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000109 | 329 | | | |
+------------------+----------+--------------+------------------+-------------------+

现在通过binlog2sql进行生成反向SQL,binlog2sql可以指定生成那个库的那个表的标准SQL或者反向SQL,带一个-t的选择:

[root@db_server_xuanzhi ~]# python binlog2sql.py -uflashuser -h127.0.0.1 -pflash123 -dxuanzhi -ttb1 --start-file='mysql-bin.000109' -B  > rollback_tb1.sql
[root@db_server_xuanzhi ~]# cat rollback_tb1.sql
INSERT INTO `xuanzhi`.`tb1`(`id`, `name`) VALUES (4, 'dd'); #start 4 end 298 time 2017-03-23 12:39:20
INSERT INTO `xuanzhi`.`tb1`(`id`, `name`) VALUES (3, 'cc'); #start 4 end 298 time 2017-03-23 12:39:20

我们可以看刚刚对tb1进行误删的操作,都生成了反向的SQL语句也就是INSERT INTO,我们进行导入操作,看数据能否正常恢复

[root@db_server_xuanzhi ~]#mysql -uroot -p123456 <./rollback_tb1.sql
Warning: Using a password on the command line interface can be insecure.
[root@db_server_xuanzhi ~]#

登录查看一下数据:

mysql> select * from tb1;
+----+------+
| id | name |
+----+------+
| 1 | aa |
| 2 | bb |
| 3 | cc |
| 4 | dd |
+----+------+
4 rows in set (0.00 sec) mysql>

可以看到数据可以正常的恢复。

模拟二:误操作把一个表的数据删除了,经常出现的就是delete没带where条件

mysql> select * from tb1;
+----+------+
| id | name |
+----+------+
| 1 | aa |
| 2 | bb |
| 3 | cc |
| 4 | dd |
+----+------+
4 rows in set (0.00 sec) mysql> delete from tb1;
Query OK, 4 rows affected (0.00 sec) mysql> select * from tb1;
Empty set (0.00 sec) mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000110 | 345 | | | |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec) mysql>

我们用bin2log对这个表进行恢复:

[root@db_server_xuanzhi ~]# python binlog2sql.py -uflashuser -h127.0.0.1 -pflash123 -dxuanzhi -ttb1 --start-file='mysql-bin.000110' -B  > rollback_tb1.sql
[root@db_server_xuanzhi ~]# cat rollback_tb1.sql
INSERT INTO `xuanzhi`.`tb1`(`id`, `name`) VALUES (4, 'dd'); #start 4 end 314 time 2017-03-23 13:37:29
INSERT INTO `xuanzhi`.`tb1`(`id`, `name`) VALUES (3, 'cc'); #start 4 end 314 time 2017-03-23 13:37:29
INSERT INTO `xuanzhi`.`tb1`(`id`, `name`) VALUES (2, 'bb'); #start 4 end 314 time 2017-03-23 13:37:29
INSERT INTO `xuanzhi`.`tb1`(`id`, `name`) VALUES (1, 'aa'); #start 4 end 314 time 2017-03-23 13:37:29
[root@db_server_xuanzhi ~]# mysql -uroot -p123456 <./rollback_tb1.sql
Warning: Using a password on the command line interface can be insecure.

再查询一下,数据是否把数据恢复了:

mysql> select * from tb1;
Empty set (0.00 sec) <Slave_1>[xuanzhi]> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000110 | 345 | | | |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec) mysql> select * from tb1;
+----+------+
| id | name |
+----+------+
| 1 | aa |
| 2 | bb |
| 3 | cc |
| 4 | dd |
+----+------+
4 rows in set (0.00 sec) mysql>

可以看到可以正常恢复,但值得注意的是drop table 和truncate table 是无法生成反向SQL的,所以建议线上程序账号只给insert,upfate,select,delete权限。

参考文章:

https://www.cnblogs.com/xuanzhi201111/p/6602489.html

https://github.com/danfengcao/binlog2sql

https://github.com/danfengcao/binlog2sql/blob/master/example/mysql-flashback-priciple-and-practice.md

总结:一、线上要对程序做好最小化权限控制,这样可以减少很多不必要的麻烦。

二、现在开源比较好用的数据闪回工具有mysqlbinlog_flashbackbinlog2sql,给DBA日常维护带来了许多帮助。

mysql闪回工具--binlog2sql实践的更多相关文章

  1. MySQL 闪回工具之 binlog2sql

    生产上误删数据.误改数据的现象也是时常发生的现象,作为 DBA 这时候就需要出来补锅了,最开始的做法是恢复备份,然后从中找到需要的数据再进行修复,但是这个时间太长了,对于大表少数数据的修复来讲,动作太 ...

  2. Mysql闪回工具之binlog2sql的原理及其使用

    生产上误删数据.误改数据的现象也是时常发生的现象,作为运维这时候就需要出来补锅了,最开始的做法是恢复备份,然后从中找到需要的数据再进行修复,但是这个时间太长了,对于大表少数数据的修复来讲,动作太大,成 ...

  3. MySQL闪回工具之myflash 和 binlog2sql

    MySQL闪回工具之:binlog2sql  https://github.com/danfengcao/binlog2sql MYSQL Binglog分析利器:binlog2sql使用详解  :h ...

  4. MySQL闪回工具之binlog2sql

    一.binlog2sql 1.1 安装binlog2sql git clone https://github.com/danfengcao/binlog2sql.git && cd b ...

  5. (4.11)mysql备份还原——mysql闪回技术(基于binlog)

    0.闪回技术与工具简介 mysql闪回工具比较流行三大类: [0.1]官方的mysqlbinlog:支持数据库在线/离线,用脚本处理binlog的输出,转化成对应SQL再执行.通用性不好,对正则.se ...

  6. binlog2sql闪回工具的使用

    binlog2sql闪回工具的使用 一.下载安装依赖的python yum install openssl-devel bzip2-devel expat-devel gdbm-devel readl ...

  7. MySQL闪回原理与实战

    本文将介绍闪回原理,给出笔者的实战经验,并对现存的闪回工具作比较. DBA或开发人员,有时会误删或者误更新数据,如果是线上环境并且影响较大,就需要能快速回滚.传统恢复方法是利用备份重搭实例,再应用去除 ...

  8. mysql 闪回原理

    利用MySQL闪回技术恢复误删除误更改的数据 笔者相信很多人都遇到过忘带where条件或者where条件漏写了一个和写错了的情况,结果执行了delete/update后把整张表的数据都给改了.传统的解 ...

  9. Mysql 之闪回技术 binlog2sql

    1.下载 https://github.com/danfengcao/binlog2sql http://rpmfind.net Search: python-pip pip 是一个Python包管理 ...

随机推荐

  1. Python第十三章-网络编程

    网络编程 一.网络编程基础 python 的网络编程模块主要支持两种Internet协议: TCP 和 UDP. 1.1通信协议 通信协议也叫网络传输协议或简称为传送协议(Communications ...

  2. G 树的难题

    时间限制 : 10000 MS   空间限制 : 165536 KB 评测说明 : 1s,128m 问题描述 给出一个无根树.树有N个点,边有权值.每个点都有颜色,是黑色.白色.灰色这三种颜色之一,称 ...

  3. Blazor入门笔记(1)-从0构建一个组件

    1.环境 VS2019 16.5.1 .NET Core SDK 3.1.200 Blazor WebAssembly Templates 3.2.0-preview2.20160.5 2.创建项目 ...

  4. Boxes Packing

    Boxes Packing Mishka has got n empty boxes. For every i (1 ≤ i ≤ n), i-th box is a cube with side le ...

  5. Java 程序该怎么优化?(命令篇)

    灵魂拷问,JDK 提供的命令,除了 java.javac,你还用过哪些命令呢? 灵魂再拷问,若你写的 Java 程序,出现了性能问题,该怎么去排查呢? Java 作为编程语言中的战斗机,JDK 默认已 ...

  6. SQL Server中STATISTICS IO物理读和逻辑读的误区

    SQL Server中STATISTICS IO物理读和逻辑读的误区 大家知道,SQL Server中可以利用下面命令查看某个语句读写IO的情况 SET STATISTICS IO ON 那么这个命令 ...

  7. @Configuration和@Bean 配置类注入

    @Configuration和@Bean 1. 概述 @Configuration 注解标记在类上, 就像下面的配置文件. 我们将该类成为配置类. <?xml version="1.0 ...

  8. 使用gulp自动构建项目

    网址:https://segmentfault.com/a/1190000011514257

  9. VMwareWorkstation如何设置共享文件夹

    首先需要安装VMware Tools 这个嘛,应该是需要安装的,之前没有安装好像就没有设置成功. 没有安装的参考如何安装VMware Tools 然后在虚拟机设置里面设置共享路径 右键虚拟机名称,打开 ...

  10. Fastdfs文件系统扩容

    1.简介     FastDFS文件服务器在设计时,为了支持大容量,存储节点(服务器)采用了分卷(或分组)的组织方式.存储系统由一个或多个卷组成,卷与卷之间的文件是相互独立的,所有卷的文件容量累加就是 ...