binlog2sql之MySQL数据闪回实践
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 =
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-bin.000107 | 120 | | | |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec) mysql> select * from tb1;
+------+------+
| id | name |
+------+------+
| 1 | aa |
| 2 | bb |
+------+------+
2 rows in set (0.00 sec) mysql>
我们现在进行数据的DML操作:
mysql> insert into tb1 values (3,'cc');
Query OK, 1 row affected (0.00 sec) mysql> insert into tb1 values (4,'dd');
Query OK, 1 row affected (0.00 sec) mysql> update tb1 set name='new_aa' where id=1;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0 mysql> delete from tb1 where id=2;
Query OK, 1 row affected (0.00 sec) mysql> select * from tb1;
+------+--------+
| id | name |
+------+--------+
| 1 | new_aa |
| 3 | cc |
| 4 | dd |
+------+--------+
3 rows in set (0.00 sec) mysql>
下面我们使用binlog2sql进行格式为ROW的binlog生成标准SQL,带个-d的参数指定库名:
[root@db_server_xuanzhi ~]#python binlog2sql.py -uflashuser -h127.0.0. -pflash123 -dxuanzhi --start-file='mysql-bin.000107' > xuanzhi.sql
[root@db_server_xuanzhi ~]#cat xuanzhi.sql
INSERT INTO `xuanzhi`.`tb1`(`id`, `name`) VALUES (, 'cc'); #start end time -- ::
INSERT INTO `xuanzhi`.`tb1`(`id`, `name`) VALUES (, 'dd'); #start end time -- ::
UPDATE `xuanzhi`.`tb1` SET `id`=, `name`='new_aa' WHERE `id`= AND `name`='aa' LIMIT ; #start end time -- ::
DELETE FROM `xuanzhi`.`tb1` WHERE `id`= AND `name`='bb' LIMIT ; #start end time -- ::
[root@db_server_xuanzhi ~]#
我们可以看到,刚刚执行过的sql都生成出来了。
我们现在对xuanzhi这个库的所有操作生成反向SQL,这个时候需要在上面语句的基础上带一个-B参数,就是flashback闪回的意思:
[root@db_server_xuanzhi ~]#python binlog2sql.py -uflashuser -h127.0.0. -pflash123 -dxuanzhi --start-file='mysql-bin.000107' -B > rollback_xuanzhi.sql
[root@db_server_xuanzhi ~]#cat rollback_xuanzhi.sql
INSERT INTO `xuanzhi`.`tb1`(`id`, `name`) VALUES (, 'bb'); #start end time -- ::
UPDATE `xuanzhi`.`tb1` SET `id`=, `name`='aa' WHERE `id`= AND `name`='new_aa' LIMIT ; #start end time -- ::
DELETE FROM `xuanzhi`.`tb1` WHERE `id`= AND `name`='dd' LIMIT ; #start end time -- ::
DELETE FROM `xuanzhi`.`tb1` WHERE `id`= AND `name`='cc' LIMIT ; #start end time -- ::
[root@db_server_xuanzhi ~]#
可以看到生成了跟上面标准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. -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 (, 'dd'); #start end time -- ::
INSERT INTO `xuanzhi`.`tb1`(`id`, `name`) VALUES (, 'cc'); #start end time -- ::
我们可以看刚刚对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. -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 (, 'dd'); #start end time -- ::
INSERT INTO `xuanzhi`.`tb1`(`id`, `name`) VALUES (, 'cc'); #start end time -- ::
INSERT INTO `xuanzhi`.`tb1`(`id`, `name`) VALUES (, 'bb'); #start end time -- ::
INSERT INTO `xuanzhi`.`tb1`(`id`, `name`) VALUES (, 'aa'); #start end time -- ::
[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权限。
还有很多选项--stop-position/--end-pos stop-file、--start-datetime/--stop-datetime这些选项就不一 一说明了,binlog2sql总的来说还是比较好用与实用的,以前写过一篇博客binlog-rollback.pl 的博客,这个脚本也可以实现,但遇到比较大的binlog就可能会出现一些问题,下面是我在线上测试对1.1G的binlog用binlog2sql进行解析的时间(阿里云的SSD盘):
参考文章:
https://github.com/danfengcao/binlog2sql
https://github.com/danfengcao/binlog2sql/blob/master/example/mysql-flashback-priciple-and-practice.md
总结:一、线上要对程序做好最小化权限控制,这样可以减少很多不必要的麻烦。
二、现在开源比较好用的数据闪回工具有mysqlbinlog_flashback和binlog2sql,给DBA日常维护带来了许多帮助。
作者:陆炫志 出处:xuanzhi的博客 http://www.cnblogs.com/xuanzhi201111 您的支持是对博主最大的鼓励,感谢您的认真阅读。本文版权归作者所有,欢迎转载,但请保留该声明。 |
binlog2sql之MySQL数据闪回实践的更多相关文章
- Mysql 之闪回技术 binlog2sql
1.下载 https://github.com/danfengcao/binlog2sql http://rpmfind.net Search: python-pip pip 是一个Python包管理 ...
- MySQL Flashback 闪回功能详解
1. 简介 mysqlbinlog flashback(闪回)用于快速恢复由于误操作丢失的数据.在DBA误操作时,可以把数据库恢复到以前某个时间点(或者说某个binlog的某个pos).比如忘了带wh ...
- ORACLE数据闪回
ALTER TABLE SPM_CON_PAYMENT_RECEIPT ENABLE ROW MOVEMENT; -- 表名 FLASHBACK TABLE SPM_CON_PAYMENT_REC ...
- mysql闪回工具--binlog2sql实践
DBA或开发人员,有时会误删或者误更新数据,如果是线上环境并且影响较大,就需要能快速回滚.传统恢复方法是利用备份重搭实例,再应用去除错误sql后的binlog来恢复数据.此法费时费力,甚至需要停机维护 ...
- (4.11)mysql备份还原——mysql闪回技术(基于binlog)
0.闪回技术与工具简介 mysql闪回工具比较流行三大类: [0.1]官方的mysqlbinlog:支持数据库在线/离线,用脚本处理binlog的输出,转化成对应SQL再执行.通用性不好,对正则.se ...
- 技术分享 | 浅谈MySQL闪回的实现
欢迎来到 GreatSQL社区分享的MySQL技术文章,如有疑问或想学习的内容,可以在下方评论区留言,看到后会进行解答 1.闪回实现原理 2.binlog文件格式初探 3.闪回实现过程 1.闪回实现原 ...
- mysql 闪回原理
利用MySQL闪回技术恢复误删除误更改的数据 笔者相信很多人都遇到过忘带where条件或者where条件漏写了一个和写错了的情况,结果执行了delete/update后把整张表的数据都给改了.传统的解 ...
- oracle 数据被修改怎么修复?(闪回)
数据被删除 或者 update 的时候忘记勾选where 限制条件,数据全部更新了? 怎么办? 要跑路了? NO !!! 看下面,迅速帮你闪回数据! demo sql: 1. SELECT * FR ...
- ORACLE数据库数据被修改或者删除恢复数据(闪回)
1. SELECT * FROM CT_FIN_RiskItem --先查询表,确定数据的确不对 (cfstatus 第一行缺少) 2. select * from CT_FIN_RiskItem ...
随机推荐
- 关于java11 - 应该知道的
Local Variable Type Inference# HTTP Client# Collections# Streams# Optionals# Strings# InputStreams# ...
- 第一节,tensorflow基础构架
1.tensorflow结构 import tensorflow as tfimport numpy as np #create datax_data=np.random.rand(100).asty ...
- linux 安装图行界面
centos6的环境中 代码:[root@ebs122 sysconfig]#yum groupinstall "Desktop" 使用 init 5命令进入图形化界面,如果成功的 ...
- Kivy折腾笔记
最近想用Python开发APP,选择kivy,记录过程 首先是源码安装,各种蛋疼的报错放弃了.cython高版本有问题. python3 -m pip install cython==0.23 pyt ...
- [转] 图 + 文 + 公式 理解LSTM
转自公号“机器之心” LSTM入门必读:从入门基础到工作方式详解 长短期记忆(LSTM)是一种非常重要的神经网络技术,其在语音识别和自然语言处理等许多领域都得到了广泛的应用..在这篇文章中,Edwin ...
- win7系统查看硬盘序列号步骤
1.在开始那里输入cmd,打开命令窗口: 2.输入diskpart,按enter键,进入底盘查看选项: 3.输入list disk,按回车键: list disk:查看电脑上有几块硬盘: 输入sele ...
- python 之路,Day 1 python基础 之 课后随笔
首先是抱着被忽悠的心态,购买了老男孩的什么什么什么(你懂得!!),开始了一周一堂课时的听,然后就是做,自己的博客,首先附上整理的内容吧. 1day .... 一. Hell world 程序 在lin ...
- CAD版本 注册表信息
AutoCAD2002 AutoCAD.Application.15 AutoCAD2003 AutoCAD.Application.15.1 AutoCAD2004 AutoCAD.Applic ...
- 题解-ZJOI2015地震后的幻想乡
Problem bzoj & 洛谷 题意简述:给定一个\(n\)(\(n\leq 10\))个点\(m\)条边的无向图,每条边的权值为一个\(0\)到\(1\)之间的连续随机变量,求图的最小生 ...
- ubuntu安装 opencv-3.4.3
1 .官网(https://opencv.org/releases.html)下载下源码 opencv-3.4.3.zip 2.解压 unzip opencv-3.4.3.zip 3.cmake c ...