mysql的数据恢复

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS MySQL,高可用系列 2核4GB
简介:

数据库数据被误删除是经常看到的事情,数据的恢复也就自然成为了DBA很重要的一门基本功夫,比较笨拙的办法是拉出历史的备份到另外的一台机器恢复出来,但是这种方法如果数据量比较大的话,往往会耗费较长的时间,以前在使用oracle的时候,提供了很多数据恢复的办法,常用的办法就是采用闪回flashback,或者通过logmnr在分析日志完成数据的恢复,但是在mysql中,数据的恢复变成了很困难的一件事情。
上周一同事的数据库就由于开发人员的数据订正误操作,导致了一张表的所有数据被清空,由于该库的数据容量已经达到了几百G,从备份中恢复需要很长的时间,所以联系到我帮助恢复,由于数据库采用的是row模式,删除的操作在binlog中会一行一行的记录,所以恢复操作就是将binlog中的内容进行解析为对应的插入语句,恢复步骤如下:
1.用mysqlbing将binlog文件进行解析:
mysqlbinlog -vvv /home/mysql/data3006/mysql/mysql-bin.000004 >/tmp/master.log.20120925
2.由于被误删除的表有13个字段,在加上两行delete和where,所以取其中的15行:
grep “###” master.log.20120925 | grep “DELETE FROM master.agentgroup” -A 15 >/tmp/xx.log
root@db1.com # more /tmp/xx.log
### DELETE FROM master.del_table
### WHERE
### @1=15 /* INT meta=0 nullable=0 is_null=0 */
### @2=1 /* INT meta=0 nullable=0 is_null=0 */
### @3=2010-09-07 18:03:13 /* DATETIME meta=0 nullable=0 is_null=0 */
### @4=1 /* INT meta=0 nullable=0 is_null=0 */
### @5=2012-09-24 01:13:56 /* DATETIME meta=0 nullable=0 is_null=0 */
### @6=’yahoo_yst’ /* VARSTRING(384) meta=384 nullable=0 is_null=0 */
### @7=5259 /* INT meta=0 nullable=1 is_null=0 */
### @8=22 /* INT meta=0 nullable=1 is_null=0 */
### @9=b’0′ /* BIT(1) meta=1 nullable=0 is_null=0 */
### @10=b’1′ /* BIT(1) meta=1 nullable=0 is_null=0 */
### @11=NULL /* BIT(1) meta=0 nullable=1 is_null=1 */
### @12=b’0′ /* BIT(1) meta=1 nullable=1 is_null=0 */
### @13=18170 /* INT meta=0 nullable=1 is_null=0 */
3.用sed替换’###’:

root@db1.com # more /tmp/xx.log
DELETE FROM master.del_table
WHERE
@1=15 /* INT meta=0 nullable=0 is_null=0 */
@2=1 /* INT meta=0 nullable=0 is_null=0 */
@3=2010-09-07 18:03:13 /* DATETIME meta=0 nullable=0 is_null=0 */
@4=1 /* INT meta=0 nullable=0 is_null=0 */
@5=2012-09-24 01:13:56 /* DATETIME meta=0 nullable=0 is_null=0 */
@6=’yahoo_yst’ /* VARSTRING(384) meta=384 nullable=0 is_null=0 */
@7=5259 /* INT meta=0 nullable=1 is_null=0 */
@8=22 /* INT meta=0 nullable=1 is_null=0 */
@9=b’0′ /* BIT(1) meta=1 nullable=0 is_null=0 */
@10=b’1′ /* BIT(1) meta=1 nullable=0 is_null=0 */
@11=NULL /* BIT(1) meta=0 nullable=1 is_null=1 */
@12=b’0′ /* BIT(1) meta=1 nullable=1 is_null=0 */
@13=18170 /* INT meta=0 nullable=1 is_null=0 */

4.替换’*/’为’,’:
root@db1.com # sed -i ‘s/\*\//\*\/,/g’ /tmp/xx.log
root@db1.com # more /tmp/xx.log
DELETE FROM master.del_table
WHERE
@1=15 /* INT meta=0 nullable=0 is_null=0 */,
@2=1 /* INT meta=0 nullable=0 is_null=0 */,
@3=2010-09-07 18:03:13 /* DATETIME meta=0 nullable=0 is_null=0 */,
@4=1 /* INT meta=0 nullable=0 is_null=0 */,
@5=2012-09-24 01:13:56 /* DATETIME meta=0 nullable=0 is_null=0 */,
@6=’yahoo_yst’ /* VARSTRING(384) meta=384 nullable=0 is_null=0 */,
@7=5259 /* INT meta=0 nullable=1 is_null=0 */,
@8=22 /* INT meta=0 nullable=1 is_null=0 */,
@9=b’0′ /* BIT(1) meta=1 nullable=0 is_null=0 */,
@10=b’1′ /* BIT(1) meta=1 nullable=0 is_null=0 */,
@11=NULL /* BIT(1) meta=0 nullable=1 is_null=1 */,
@12=b’0′ /* BIT(1) meta=1 nullable=1 is_null=0 */,
@13=18170 /* INT meta=0 nullable=1 is_null=0 */,
DELETE FROM master.del_table
5.替换日志中的最后一个’,’为’;’:
a.delete前加’;’:
sed -i ‘s/DELETE/;DELETE/g’ /tmp/xx.log
root@db1.com # more /tmp/xx.log
DELETE FROM master.del_table
WHERE
@1=15 /* INT meta=0 nullable=0 is_null=0 */,
@2=1 /* INT meta=0 nullable=0 is_null=0 */,
@3=2010-09-07 18:03:13 /* DATETIME meta=0 nullable=0 is_null=0 */,
@4=1 /* INT meta=0 nullable=0 is_null=0 */,
@5=2012-09-24 01:13:56 /* DATETIME meta=0 nullable=0 is_null=0 */,
@6=’yahoo_yst’ /* VARSTRING(384) meta=384 nullable=0 is_null=0 */,
@7=5259 /* INT meta=0 nullable=1 is_null=0 */,
@8=22 /* INT meta=0 nullable=1 is_null=0 */,
@9=b’0′ /* BIT(1) meta=1 nullable=0 is_null=0 */,
@10=b’1′ /* BIT(1) meta=1 nullable=0 is_null=0 */,
@11=NULL /* BIT(1) meta=0 nullable=1 is_null=1 */,
@12=b’0′ /* BIT(1) meta=1 nullable=1 is_null=0 */,
@13=18170 /* INT meta=0 nullable=1 is_null=0 */,
;DELETE FROM master.del_table
b.delete 前的’,;’替换为’;’:
vi /tmp/xx.log —–>:%s/,$\n^ ;/;/g
DELETE FROM master.del_table
WHERE
@1=29 /* INT meta=0 nullable=0 is_null=0 */,
@2=1 /* INT meta=0 nullable=0 is_null=0 */,
@3=2010-09-07 18:03:13 /* DATETIME meta=0 nullable=0 is_null=0 */,
@4=1 /* INT meta=0 nullable=0 is_null=0 */,
@5=2012-06-01 13:05:00 /* DATETIME meta=0 nullable=0 is_null=0 */,
@6=’alipay_front_jx’ /* VARSTRING(384) meta=384 nullable=0 is_null=0 */,
@7=5267 /* INT meta=0 nullable=1 is_null=0 */,
@8=58 /* INT meta=0 nullable=1 is_null=0 */,
@9=b’0′ /* BIT(1) meta=1 nullable=0 is_null=0 */,
@10=b’1′ /* BIT(1) meta=1 nullable=0 is_null=0 */,
@11=NULL /* BIT(1) meta=0 nullable=1 is_null=1 */,
@12=b’0′ /* BIT(1) meta=1 nullable=1 is_null=0 */,
@13=NULL /* BIT(1) meta=0 nullable=1 is_null=1 */
;DELETE FROM master.del_table
@1,@2,@3….对应的是表的字段;
6.最后将delete from table xx where 改为insert into xx values(”,”,”,”…..)既可以;
通过上面的6个步骤就可以从binlog中恢复出删除的数据,看上去很繁琐,所以parse_binlog 工具就产生了,这个工具是@俊达 所写,可以将row模式的binlog转换为对应的sql语句:

mysql> USE T1
Database changed
mysql> delete from t1 where id<12;
Query OK, 2 rows affected (0.00 sec)

mysqlbinlog -vvv /home/mysql/data3006/mysql/mysql-bin.000004 |/root/parse_binlog.pl >/tmp/parse.sql1
more /tmp/parse/sql1
–DML type: DELETE, num of cols: 2
replace into t1.t1 values ( 10 , ‘ni hao1’);
–DML type: DELETE, num of cols: 2
replace into t1.t1 values ( 11 , ‘ni hao1’);

这样DBA就可以方便的进行数据的恢复了;

最近@plinux已经完成该mysql闪回方案补丁,在row模式的binlog下,记录了每个ROW的完整信息,INSERT会包含每个字段的值,DELETE也会包含每个字段的值,UPDATE会在SET和WHERE部分包含所有的字段值。因此binlog就是个完整的逻辑redo,把它的操作逆过来,就是需要的“undo”;@吴炳锡 这个好人已经把他编译好了放在开源社区上,可以在这里下载:

mysql> show master logs;
+——————+———–+
| Log_name | File_size |
+——————+———–+
| mysql-bin.000004 | 2293035 |
+——————+———–+
mysql> use t1
Database changed

mysql> delete from t1 where id=15;
Query OK, 1 row affected (0.00 sec)

mysql> show master logs;
+——————+———–+
| Log_name | File_size |
+——————+———–+
| mysql-bin.000004 | 2293211 |
+——————+———–+

root@db.com # ./mysqlbinlog.txt -v –base64-output=decode-rows -B –start-position=2293035 /home/mysql/data3006/mysql/mysql-bin.000004 >/tmp/1.sql
root@db.com # more /tmp/1.sql
DELIMITER ;
#121004 19:59:35 server id 3703006010 end_log_pos 2293211 Xid = 13145226
COMMIT/*!*/;
#121004 19:59:35 server id 3703006010 end_log_pos 2293143 Table_map: `t1`.`t1` mapped to number 1584
#121004 19:59:35 server id 3703006010 end_log_pos 2293184 Delete_rows: table id 1584 flags: STMT_END_F
### INSERT INTO t1.t1
### SET
### @1=15
### @2=’ni xxx’
DELIMITER ;

不得不说开源的力量真大.

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
关系型数据库 MySQL 数据库
阿里云MySQL线上备份数据恢复
阿里云MySQL线上备份数据恢复
|
6月前
|
SQL 弹性计算 关系型数据库
服务器数据恢复-华为ECS云服务器mysql数据库数据恢复案例
云服务器数据恢复环境: 华为ECS云服务器,linux操作系统,mysql数据库(innodb引擎)。作为网站服务器使用。 云服务器故障: 在执行mysql数据库版本更新测试时,误将本应该在测试库上执行的sql脚本执行在生产库上了,生产库上的部分表被truncate,部分表内有少量数据被delete。 需要恢复被truncate的表以及被少量数据被delete的表。
服务器数据恢复-华为ECS云服务器mysql数据库数据恢复案例
|
3月前
|
SQL 存储 关系型数据库
【MySQL核心】MySQL 数据恢复-ibd2sql
【MySQL核心】MySQL 数据恢复-ibd2sql
|
3月前
|
编解码 缓存 关系型数据库
【MySQL 核心】MySQL数据恢复-dbsake
【MySQL 核心】MySQL数据恢复-dbsake
|
4月前
|
SQL 存储 关系型数据库
|
4月前
|
存储 关系型数据库 MySQL
|
6月前
|
SQL 关系型数据库 MySQL
【MySQL技术专题】「问题实战系列」深入探索和分析MySQL数据库的数据备份和恢复实战开发指南(数据恢复补充篇)(一)
【MySQL技术专题】「问题实战系列」深入探索和分析MySQL数据库的数据备份和恢复实战开发指南(数据恢复补充篇)
68 0
|
6月前
|
关系型数据库 MySQL Shell
【MySQL技术专题】「问题实战系列」深入探索和分析MySQL数据库的数据备份和恢复实战开发指南(数据恢复补充篇)(二)
【MySQL技术专题】「问题实战系列」深入探索和分析MySQL数据库的数据备份和恢复实战开发指南(数据恢复补充篇)
39 0
|
存储 关系型数据库 MySQL
数据库数据恢复—MySQL数据库误删除表数据的数据恢复案例
数据库数据恢复环境: 一台本地windows sever操作系统服务器,服务器上部署mysql数据库单实例,引擎类型为innodb,表内数据存储所使用表空间类型为独立表空间。无数据库备份,未开启binlog。 数据库故障&分析: 工作人员在执行Delete命令删除数据时未添加where子句进行筛选,导致全表数据被删除,删除后未对该表进行其他操作。
数据库数据恢复—MySQL数据库误删除表数据的数据恢复案例
|
6月前
|
SQL 关系型数据库 MySQL
数据库数据恢复—windows server下Mysql数据库数据恢复案例
mysql数据库数据恢复环境: 本地服务器,windows server操作系统 ,部署有mysql单实例,数据库引擎类型为innodb,独立表空间,无数据库备份,未开启binlog。 mysql数据库故障: 工作人员使用Delete命令删除数据时未添加where子句进行筛选,导致全表数据被删除,删除后未对该表进行任何操作。