Mysql binlog数据恢复(使用mysqlbinlog_flashback逆向生成SQL语句)
这里有个建议,由于mysql默认是不开启binlog的,如果是线上数据库,或者比较重要的数据库,建议还是将binlog开启,而且格式设为ROW类型的。
防止出现问题时,也有恢复的退路,养成定期备份数据库的习惯。
通过命令,查看是否开启了binlog。
show variables like 'log_%';
数据恢复方法:
1.用最近的全量备份,然后在加上全量备份时间点后的binlog日志,然后先还原全量备份,在通过命令把binlog执行掉,这样数据就能还原了,这种方法,不限binlog的日志格式,ROW或者MIXED都行。但是随着业务量增大,可能单次还原数据库和执行binlog需要很长时间。
2.只用binlog日志,将binlog日志解析出来,生成反向原始sql,然后执行还原数据,这种方式binlog日志格式需要是ROW
下面开始模拟,数据修改出错,或者数据误删进行数据恢复,基于第二种方法。
目录
- 1.环境模拟
- 2.往表中插入数据
- 3.模拟线上更改1个表数据,删除1个数据,并查看更改日志
- 4.还原数据
1.环境模拟
先建1个库,然后建1个表,
建表语句如下
CREATE TABLE `table_test1` (`id` int(11) NOT NULL AUTO_INCREMENT,`name` varchar(50) DEFAULT '' COMMENT '姓名',`sex` int(1) DEFAULT '1' COMMENT '性别',`age` int(3) DEFAULT '18' COMMENT '年龄',PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
2.往表中插入数据
insert into binlog_test1.table_test1 VALUES(1,'张三1',1,19);
insert into binlog_test1.table_test1 VALUES(2,'李四1',1,19);
insert into binlog_test1.table_test1 VALUES(3,'王五1',1,19);
数据插入进去后,我们通过mysqlbinlog 命令看看binlog日志内容
mysqlbinlog --no-defaults E:\......\mysql-5.6.35-winx64\logs\mysql-bin.000001
可以看到我们新增的数据都在日志中,随便抓一个片段,来解释下日志内容。
/*!*/;
# at 483
#210222 10:56:11 server id 1 end_log_pos 563 CRC32 0xc52b14e5 Query thread_id=1 exec_time=0 error_code=0
SET TIMESTAMP=1613962571/*!*/;
BEGIN
/*!*/;
# at 563
#210222 10:56:11 server id 1 end_log_pos 630 CRC32 0xbf00ad20 Table_map: `binlog_test1`.`table_test1` mapped to number 70
# at 630
#210222 10:56:11 server id 1 end_log_pos 686 CRC32 0x4473d9af Write_rows: table id 70 flags: STMT_END_FBINLOG '
Sx0zYBMBAAAAQwAAAHYCAAAAAEYAAAAAAAEADGJpbmxvZ190ZXN0MQALdGFibGVfdGVzdDEABAMP
AwMClgAOIK0Avw==
Sx0zYB4BAAAAOAAAAK4CAAAAAEYAAAAAAAEAAgAE//ABAAAAB+W8oOS4iTEBAAAAEwAAAK/Zc0Q=
'/*!*/;
# at 686
#210222 10:56:11 server id 1 end_log_pos 717 CRC32 0x115267fc Xid = 21
COMMIT/*!*/;
# at 717
#210222 10:56:11 server id 1 end_log_pos 797 CRC32 0xb521ac31 Query thread_id=1 exec_time=0 error_code=0
SET TIMESTAMP=1613962571/*!*/;
BEGIN
#at 483:事件的起点
#210222 10:56:11:事件记录的时间
server id 1:服务器标识,默认1
end_log_pos 563:事件结束的位置,第366字节
CRC320xc52b14e5:checksum主从复制校验值
Xid = 21:事务id
3.模拟线上更改1个表数据,删除1个数据,并查看更改日志
先将 table_test1 表中,id为3的数据更改下
update table_test1 set sex=0 where id=3;
delete from table_test1 where id=2;
在通过命令看下日志
可以看到更改的数据在日志中,且是有库和表的信息的,说明不管多少个库和表,binlog是互不影响的,都是具体到哪个库里的哪个表,
这样后面还原数据的时候就可以指定库和表,防止数据量太大。
还可以用
show binlog events in "mysql-bin.000001"
这个命令查看
4.还原数据
还原数据之前可以先用命令查询下当前binlog的position并刷新下日志,这样当前需要还原的日志里面就不会有新数据进去了,会重新生成一个日志文件,这个步骤看需要。主要就是防止数据过多影响恢复。
#查询position
show master status
#刷新日志,可以不刷新,看需求
flush logs
先将binlog日志导出,
mysqlbinlog --no-defaults -v --base64-output=decode-rows --start-position=1265 --stop-position=1675 --database=binlog_test1 E:\......\mysql-5.6.35-winx64\logs\mysql-bin.000001 > E:\......\mysql-5.6.35-winx64\logs\data.sql
参数说明:
--no-defaults :不要读任何选项文件,不加这个命令会报错
--start-position= :起始pos点,例如:--start-position=110
--stop-position= :结束pos点,例如:--stop-position=200
--start-datetime= :起始时间,例如:--start-datetime="2020-07-18 19:00:00"
--stop-datetime= :截至时间,例如:--stop-datetime="2020-07-18 21:00:00"
--database= :指定哪个库,例如:-database=binlog_test1
-v :生成带注释的sql语句(这是重点,反向还原需要看这个sql)
-v -v:生成列的的描述信息备注等
--base64-output=decode-rows :binlog部分是否显示出来的,decode-rows表示不显示binglog部分
文件导出后,我们再看看文件内容是什么
能看到当时执行sql的完整sql,包括这条数据修改之前的数据,然后我们就可以手动更改还原数据。当然如果数据是批量更改的,且整个binlog中有很多日志,那么就需要过滤条件找到需要还原的数据日志,然后再通过工具,将日志批量转换成反向sql执行。
这里推荐一个逆向工具mysqlbinlog_flashback,
源码地址:https://github.com/58daojia-dba/mysqlbinlog_flashback
使用python实现的,环境python2.6,我试的时候用的2.7也没问题,然后需要装包,特别是pymysql
下载完源码后需要改2个地方,这是目前知道有问题的地方。
第一个是row_event.py,把charset_to_encoding注释掉,发现读取的时候少了编码也没啥问题,如果不注释掉会报错提示找不到,也不知道为啥这个版本的pymysql没有charset_to_encoding
第二个可能是作者的一个bug
这里判断版本大小的时候,如果pymysql的版本是 0.5.1 这样的是没问题的。但是如果版本是 0.10.1这样的,这个判断就是不对的。因为不知道这种判断存在多少,所以最粗暴的方式就是直接去改下pymysql的版本。
通过跟踪代码找到版本修改的地方,改成1.10.1,这样判断就ok了。
然后可以通过 Pycharm来运行项目,这种就可以调试代码,假如出问题可以找下原因,或者直接通过cmd来运行。
python mysqlbinlog_back.py --help
可以看看有哪些命令,顺便看看想想是否能正常运行,具体的可以看README.md,有详细介绍。
然后就是最重要的逆向sql生成命令了,
--host="127.0.0.1" --port=3306 --username="root" --password="**********" --schema="数据库名称" --tables="表名称" -S "需要生成的binlog文件" -L "从哪个position开始"
--host="127.0.0.1" --port=3306 --username="root" --password="abcdefg" --schema="test" --tables="table_test" -S "mysql-bin.000001" -L "4"
这里有几个注意点,首先第一个正常情况下,如果要还原数据,我们是不敢直接去连真实数据库去操作的,那么肯定要把binlog拷到本地来,在本地还原好数据后在同步到真实环境。
首先把真实环境的binlog拷到本地的binlog目录,binlog可能是mysql-bin.009999这样的。本地可能只到mysql-bin.000005这样的。如果直接在命令里面去读mysql-bin.009999,它会报错的。
这里可以根据
SHOW BINARY LOGS;
查下本地数据库的binlog列表,然后将本地的binlog备份下,然后把mysql-bin.009999重命令下就可以了,比如将mysql-bin.000001备份下然后删除,在将mysql-bin.009999重命名为mysql-bin.000001,这是第一个细节问题。
第二个如果不是直连真实环境,那么本地新建的数据库名称以及表名需要跟真实环境的保持一致,因为binlog里面是记录这些的,扫描的时候是根据这些进行匹配的。比如真实环境是test库,table_test表,那么本地还原环境也要这样。有这个库和这个表,因为需要根据表信息去生成字段,命令中schema和tables就是本地环境的库和表
--schema="test" --tables="table_test"
执行完命令后会在mysqlbinlog_flashback-master\log地址下生成flashback_binlog_为前缀的sql文件,打开文件可以看到里面的逆向sql。
可以看到我一开始是新增3条数据,这里逆向生成3条删除数据,之前执行的命令
update table_test1 set sex=0 where id=3;
delete from table_test1 where id=2;
逆向生成一个update和insert语句
Mysql binlog数据恢复(使用mysqlbinlog_flashback逆向生成SQL语句)相关推荐
- MySQL binlog 数据恢复
不求人,MySQL Binlog数据恢复 文章目录 不求人,MySQL Binlog数据恢复 浅谈恢复形式 开启 binlog 及配置 删库跑路(搭建测试数据库,然后删除它) 起死回生(分析binlo ...
- mysql直接生成excel_MYSQL 将excel里面的数据直接生成sql语句
如何使用EXCEL生成SQL语句? 将光标放到新的列上里面,然后在公式栏里面输入如下公式: ="insert into t values('"&A1&"' ...
- mysql语句生成,SQL语句生成器
SQL语句自动生成器正式版是一款功能强大.十分实用方便的数据库编程软件,可以帮助用户简便快捷的生成sql语句,SQL语句自动生成器正式版支持桌面数据库和大中型数据库,以及排序.条件.分组.函数等多种s ...
- 码匠 × OpenAI :快速生成 SQL 语句,提升开发效率!
目录 使用 OpenAI 生成 SQL 码匠连接与集成 OpenAI 总结 关于码匠 在码匠中,编写 SQL 语句,并结合码匠一系列开箱即用的组件实现复杂的业务逻辑,是很常见的应用开发场景.然而,不同 ...
- JavaWEB01:MySQL基础——数据库相关概念、MySQL安装和配置、基础的SQL语句
JavaWEB01:MySQL基础--数据库相关概念.MySQL安装和配置.基本的SQL语句 JavaWEB02:MySQL高级--约束.数据库设计.多表查询.事务 JavaWEB03:JDBC Ja ...
- 解放程序员双手!GPT-3自动生成SQL语句 | 代码开源
金磊 发自 凹非寺 量子位 报道 | 公众号 QbitAI "无所不能"的GPT-3,现在又来解放程序员们的双手了. 像这样,只需用简单的英文问下GPT-3"上个月注册了 ...
- 用一个类根据Model属性生成SQL语句
想到写这个的原因是我和我的一个朋友在写一个开源项目的时候,我负责了数据库的持久化存储部分,结果他看到了我的数据库数据存储结构之后直接傻眼了,因为个人比较简单粗暴,直接把一个数据Model归档成为二进制 ...
- tp5循环查询语句_如何用Excel快速生成SQL语句,用过的人都说好
Excel的公式自动生成想必大家都知道了,就是写好一个公式后直接往下拖,就可以将后面数据的公式自动生成. 今天我们就用这个功能来快速生成SQL语句. 导入Excel数据 Excel的数据有多种方式,这 ...
- python sql语句生成_python Django 生成sql语句
class TestModel(models.Model): Name=models.CharField(max_length=64,blank=True) >>> from dja ...
最新文章
- 如何编写无法维护的代码 让自己稳拿铁饭碗 ;-)
- 偏移shaderuv_Unity Shader 之 uv动画
- r语言msar如何用_如何在jupyter notebook中使用R语言
- Tosca:键盘输入字符串
- GitHub简单教程
- VPP 命令总结(持续更新)
- TextToSpeech问题总结
- 夏普Sharp MX-C3581R 一体机驱动
- 什么是网络安全等级保护
- 基于Python的南京二手房数据采集及可视化分析设计
- 阿里云天池Python训练营-打卡Task3
- 星际争霸 2 快捷键
- Linux安装视频播放器
- 关于“基于模型的思想”的一些引述和评论
- ssas连接oracle性能,Analysis Services(SSAS) 性能优化
- 单片机蜂鸣器音乐播放
- MongoDB实现地理坐标服务(查询附近,查询距离)
- COOX基础培训之PMT
- 台式计算机的CPU上安装有小风扇,台式电脑cpu风扇安装教程
- [Unity]如果AssetStore的下载无效怎么办