Mysql数据闪回的奇技淫巧(binlog2sql)

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介:

一、概述

binlog2sql是一个开源项目,应用于大众点评线上环境。类似于ORACLE中的闪回功能,binlog2sql可以基于时间点或者位置偏移量进行数据恢复。MySQL binlog解析出你要的SQL。根据不同选项,你可以得到原始SQL、回滚SQL、去除主键的INSERT SQL等。也就是对于insert操作会生成对应的delete语句,反之delete操作会生出对应的insert语句,update操作会生成相反的语句。

关于binlog2sql闪回详细介绍可参闪回原理与实战。我也是偶然间看到一个大神关于这个神器的介绍,猛然心动,决心要动手演练一把。

我的测试环境介绍

Python 2.6

MySQL 5.1.73

二、binlog2sql安装

binlog2sql工具可以自己下载 https://github.com/danfengcao/binlog2sql

下面这些包都要装全,否则执行脚本会报错

python-pip

PyMySQL

python-mysql-replication

argparse

Linux机器下载并安装binlog2sql

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
[root@DB binlog2sql-master] # wget  https://codeload.github.com/danfengcao/binlog2sql/zip/master
[root@DB install_page] # unzip binlog2sql-master.zip 
Archive:  binlog2sql-master.zip
bb09b8f9079ca4d3cacd0186f35ddf4b3e1cfa7e
    creating: binlog2sql-master/
   inflating: binlog2sql-master/.gitignore  
   inflating: binlog2sql-master /LICENSE  
   inflating: binlog2sql-master /README .md  
    creating: binlog2sql-master /binlog2sql/
   inflating: binlog2sql-master /binlog2sql/__init__ .py  
   inflating: binlog2sql-master /binlog2sql/binlog2sql .py  
   inflating: binlog2sql-master /binlog2sql/binlog2sql_util .py  
    creating: binlog2sql-master /example/
   inflating: binlog2sql-master /example/mysql-flashback-priciple-and-practice .md  
   inflating: binlog2sql-master /requirements .txt  
    creating: binlog2sql-master /tests/
   inflating: binlog2sql-master /tests/test_binlog2sql_util .py  
[root@DB install_page] # ls
binlog2sql-master  binlog2sql-master.zip  
[root@DB binlog2sql-master] # cd binlog2sql-master #下面脚本执行的时候也要在这么路径下
[root@DB binlog2sql-master] # pip install -r requirements.txt 
Downloading /unpacking  PyMySQL==0.7.11 (from -r requirements.txt (line 1))
   Downloading PyMySQL-0.7.11. tar .gz (71kB): 71kB downloaded
   Running setup.py egg_info  for  package PyMySQL
Downloading /unpacking  wheel==0.29.0 (from -r requirements.txt (line 2))
   Downloading wheel-0.29.0. tar .gz (54kB): 54kB downloaded
   Running setup.py egg_info  for  package wheel
     no previously-included directories found matching  'wheel/test/*/dist'
     no previously-included directories found matching  'wheel/test/*/build'
Downloading /unpacking  mysql-replication==0.13 (from -r requirements.txt (line 3))
   Downloading mysql-replication-0.13. tar .gz
   Running setup.py egg_info  for  package mysql-replication
Installing collected packages: PyMySQL, wheel, mysql-replication
   Running setup.py  install  for  PyMySQL
   Running setup.py  install  for  wheel
     no previously-included directories found matching  'wheel/test/*/dist'
     no previously-included directories found matching  'wheel/test/*/build'
     Installing wheel script to  /usr/bin
   Running setup.py  install  for  mysql-replication
Successfully installed PyMySQL wheel mysql-replication
Cleaning up...

三、Mysql环境要求

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

1
2
3
4
5
[mysqld]
server- id =160
log-bin=mysql-binlog
max_binlog_size=1G
binlog_format=row

 

2、 创建一个闪回用户

1
2
3
4
5
6
7
root@localhost test1 19:48:06> create user  test @ '%'  identified by  '123456' ;
Query OK, 0 rows affected (0.00 sec)
root@localhost test1 19:49:06>grant  select ,replication slave,replication client on *.* to  test @ '%' ;
Query OK, 0 rows affected (0.00 sec)
  
root@localhost test1 19:49:50>flush privileges;
Query OK, 0 rows affected (0.00 sec)

注:user需要的最小权限集合:

select, super/replication client, replication slave

权限说明

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


 

3、 模拟一次生产事故,误删数据

test1tb1表原有数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
root@localhost test1 20:08:52> select  * from tb1;
+-------+------+
| name  | age  |
+-------+------+
| kobe  |   21 |
| james |   22 |
| jack  |   23 |
| mike  |   24 |
| bob   |   25 |
+-------+------+
5 rows  in  set  (0.01 sec)
  
root@localhost test1 20:08:59>delete from tb1 where age <23;
Query OK, 2 rows affected (0.00 sec)
  
root@localhost test1 20:09:03> select  * from tb1;
+-------+------+
| name  | age  |
+-------+------+
| jack  |   23 |
| mike  |   24 |
| bob   |   25 |
+-------+------+
3 rows  in  set  (0.01 sec)

四、恢复数据步骤

1登录mysql,查看目前的binlog文件

 

1
2
3
4
5
6
7
root@localhost test1 20:09:59>show master status;
+---------------------+----------+--------------+------------------+
| File                | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+---------------------+----------+--------------+------------------+
| mysql-binlog.000002 |      341 |              |                  |
+---------------------+----------+--------------+------------------+
1 row  in  set  (0.00 sec)

 

最新的binlog文件是mysql-binlog.000002,我们再定位误操作SQLbinlog位置。误操作人只能知道大致的误操作时间,我们根据大致时间过滤数据。

2、 接下来就该这个神器登场了。

先来介绍一下binlog2sql参数

1
2
3
4
5
6
7
8
9
10
11
--stop-never 持续同步binlog。可选。不加则同步至执行命令时最新的binlog位置。
-K, --no-primary-key 对INSERT语句去除主键。可选。
-B, --flashback 生成回滚语句,可解析大文件,不受内存限制,每打印一千行加一句SELECT SLEEP(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。可选。默认为空。


 

3、 根据预估时间,执行下面命令找出对应的position

1
2
3
[root@DB binlog2sql] # python binlog2sql.py -h 192.168.221.160 -utest -p123456 -dtest1 -ttb1 --start-file='mysql-binlog.000002' --start-datetime='2017-12-04 20:00:00' --stop-datetime='2017-12-04 20:10:00' 
DELETE FROM `test1`.`tb1` WHERE `age`=21 AND `name`= 'kobe'  LIMIT 1;  #start 4 end 271 time 2017-12-04 20:08:59
DELETE FROM `test1`.`tb1` WHERE `age`=22 AND `name`= 'james'  LIMIT 1;  #start 4 end 271 time 2017-12-04 20:08:59

我们得到了误操作sql的准确位置在4-271之间,再根据位置进一步过滤,使用flashback模式生成回滚sql,检查回滚sql是否正确(注:真实环境下,此步经常会进一步筛选出需要的sql。结合grep、编辑器等)

4、 使用flashback模式生成回滚sql

1
[root@DB binlog2sql] # python binlog2sql.py -h 192.168.221.160 -utest -p123456 -dtest1 -ttb1 --start-file='mysql-binlog.000002' --start-position=4 --stop-position=271 -B > tb1_rollback.sql

查看闪回导出的文件

1
2
3
[root@DB binlog2sql] # cat tb1_rollback.sql 
INSERT INTO `test1`.`tb1`(`age`, `name`) VALUES (22,  'james' );  #start 4 end 271 time 2017-12-04 20:08:59
INSERT INTO `test1`.`tb1`(`age`, `name`) VALUES (21,  'kobe' );  #start 4 end 271 time 2017-12-04 20:08:59

5、 确认回滚sql正确,执行回滚语句。登录mysql确认,数据回滚成功。

1
2
[root@DB binlog2sql] # mysql -uroot test1 -p123456 <tb1_rollback.sql 
Enter password:


6、登录数据库检验数据完整性

1
2
3
4
5
6
7
8
9
10
11
root@localhost test1 20:18:04> select  * from tb1;
+-------+------+
| name  | age  |
+-------+------+
| kobe  |   21 |
| james |   22 |
| jack  |   23 |
| mike  |   24 |
| bob   |   25 |
+-------+------+
5 rows  in  set  (0.00 sec)

可以看到,之前删除的两条数据又回来了

五、结语

binlog2sql是属于Python开发,安装与使用都很简单,易于上手,可操作性强,解析为标准SQL,方便理解、调试。但仍存在一些缺点,比如只能在mysql开启的状态下运行,不能离线操作,数据量较大时会暴露出解析速度慢的问题。总体来说,仍不失成为一个很NICE的工具。

 



本文转自 青苗飞扬 51CTO博客,原文链接:http://blog.51cto.com/qingmiao/2047363

相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
20天前
|
存储 SQL 关系型数据库
mysql 的ReLog和BinLog区别
MySQL中的重做日志和二进制日志是确保数据库稳定性和可靠性的关键组件。重做日志主要用于事务的持久性和原子性,通过记录数据页的物理修改信息来恢复未提交的事务;而二进制日志记录SQL语句的逻辑变化,支持数据复制、恢复和审计。两者在写入时机、存储方式及配置参数等方面存在显著差异。
|
2天前
|
SQL 存储 关系型数据库
【MySQL基础篇】全面学习总结SQL语法、DataGrip安装教程
本文详细介绍了MySQL中的SQL语法,包括数据定义(DDL)、数据操作(DML)、数据查询(DQL)和数据控制(DCL)四个主要部分。内容涵盖了创建、修改和删除数据库、表以及表字段的操作,以及通过图形化工具DataGrip进行数据库管理和查询。此外,还讲解了数据的增、删、改、查操作,以及查询语句的条件、聚合函数、分组、排序和分页等知识点。
【MySQL基础篇】全面学习总结SQL语法、DataGrip安装教程
|
3天前
|
SQL 关系型数据库 MySQL
数据库灾难应对:MySQL误删除数据的救赎之道,技巧get起来!之binlog
《数据库灾难应对:MySQL误删除数据的救赎之道,技巧get起来!之binlog》介绍了如何利用MySQL的二进制日志(Binlog)恢复误删除的数据。主要内容包括: 1. **启用二进制日志**:在`my.cnf`中配置`log-bin`并重启MySQL服务。 2. **查看二进制日志文件**:使用`SHOW VARIABLES LIKE &#39;log_%&#39;;`和`SHOW MASTER STATUS;`命令获取当前日志文件及位置。 3. **创建数据备份**:确保在恢复前已有备份,以防意外。 4. **导出二进制日志为SQL语句**:使用`mysqlbinlog`
22 2
|
12天前
|
存储 关系型数据库 MySQL
mysql怎么查询longblob类型数据的大小
通过本文的介绍,希望您能深入理解如何查询MySQL中 `LONG BLOB`类型数据的大小,并结合优化技术提升查询性能,以满足实际业务需求。
45 6
|
20天前
|
SQL 存储 缓存
MySQL进阶突击系列(02)一条更新SQL执行过程 | 讲透undoLog、redoLog、binLog日志三宝
本文详细介绍了MySQL中update SQL执行过程涉及的undoLog、redoLog和binLog三种日志的作用及其工作原理,包括它们如何确保数据的一致性和完整性,以及在事务提交过程中各自的角色。同时,文章还探讨了这些日志在故障恢复中的重要性,强调了合理配置相关参数对于提高系统稳定性的必要性。
|
18天前
|
SQL 关系型数据库 MySQL
MySQL 高级(进阶) SQL 语句
MySQL 提供了丰富的高级 SQL 语句功能,能够处理复杂的数据查询和管理需求。通过掌握窗口函数、子查询、联合查询、复杂连接操作和事务处理等高级技术,能够大幅提升数据库操作的效率和灵活性。在实际应用中,合理使用这些高级功能,可以更高效地管理和查询数据,满足多样化的业务需求。
56 3
|
21天前
|
SQL 关系型数据库 MySQL
MySQL导入.sql文件后数据库乱码问题
本文分析了导入.sql文件后数据库备注出现乱码的原因,包括字符集不匹配、备注内容编码问题及MySQL版本或配置问题,并提供了详细的解决步骤,如检查和统一字符集设置、修改客户端连接方式、检查MySQL配置等,确保导入过程顺利。
|
23天前
|
SQL 存储 关系型数据库
MySQL进阶突击系列(01)一条简单SQL搞懂MySQL架构原理 | 含实用命令参数集
本文从MySQL的架构原理出发,详细介绍其SQL查询的全过程,涵盖客户端发起SQL查询、服务端SQL接口、解析器、优化器、存储引擎及日志数据等内容。同时提供了MySQL常用的管理命令参数集,帮助读者深入了解MySQL的技术细节和优化方法。
|
24天前
|
SQL Oracle 关系型数据库
SQL(MySQL)
SQL语言是指结构化查询语言,是一门ANSI的标准计算机语言,用来访问和操作数据库。 数据库包括SQL server,MySQL和Oracle。(语法大致相同) 创建数据库指令:CRATE DATABASE websecurity; 查看数据库:show datebase; 切换数据库:USE websecurity; 删除数据库:DROP DATABASE websecurity;
|
24天前
|
SQL 关系型数据库 MySQL
mysql分页读取数据重复问题
在服务端开发中,与MySQL数据库进行数据交互时,常因数据量大、网络延迟等因素需分页读取数据。文章介绍了使用`limit`和`offset`参数实现分页的方法,并针对分页过程中可能出现的数据重复问题进行了详细分析,提出了利用时间戳或确保排序规则绝对性等解决方案。