转载自:http://ourmysql.com/archives/1293

数据库数据被误删除是经常看到的事情,数据的恢复也就自然成为了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的数据恢复的更多相关文章

  1. 阿里云rds mysql数据库数据恢复到ecs中

    背景:aliyun上的rds数据库快满了,于是删除了某个备份的表后面大boss说是有用的表,需要恢复回来,阿里云有7天内的物理全量备份(通过percona-xtrabackup备份的)第一时间应该延长 ...

  2. 通过bin-log对mysql进行数据恢复

    mysqlbinlog --database=数据库名 --start-date="2017-06-01 5:00:00"  --stop-date="2017-06-1 ...

  3. 使用binlog2sql针对mysql进行数据恢复

    MySQL闪回原理与实战 DBA或开发人员,有时会误删或者误更新数据,如果是线上环境并且影响较大,就需要能快速回滚.传统恢复方法是利用备份重搭实例,再应用去除错误sql后的binlog来恢复数据.此法 ...

  4. Windows Mysql binlog 数据恢复

    show variables like 'log_bin%'; 可以看到Mysql binlog为关闭状态,那我们去更改为开启状态

  5. mysql数据库数据恢复方案概括总结

    方案一:(传统方案) 备份+binlog日志增量: 方案二:(针对update.delete语句忘加where的情况) Binlog日志文件中保存有错误操作之前和之后的两组数据,将错误操作之前的数据修 ...

  6. mysql innobackupex备份实施

    最近用innobackup进行备份测试,我们只备份一个innodb类型的库,数据大小大概50多G,用innobackupex大概用了5个多小时,但是mysqldump只用了大约2个小时,这让我很费解, ...

  7. 服务器宕机,mysql无法启动,job for mysql.service failed because the process exited with error code,数据库备份与恢复

    [问题现象] 服务器在运行过程中,因人为意外导致电源被拔,服务器宕机,mysql重启不成功,报错如下 根据提示,输入systemctl status mysql.service和journalctl ...

  8. linux服务器MySQL数据从磁盘拷贝以及恢复

    偶有感触:遇到这个问题,经过一个下午的排查, 终于解决. 故事情节:我的阿里云服务器突然被黑客攻击了,整个系统down了. 找客服,他们排查说usr目录的文件全部丢失.让我重新初始化系统盘.初始化之前 ...

  9. 搭建稳固的MySQL运维体系

    MySQL 监控要点 MySQL 监控要点,主要涉及服务器和 MySQL 两个方向的监控告警. 在这两个监控告警方向需要重点关注监控策略.监控趋势图及报警方式. 监控策略指的是每个监控项的告警阈值,例 ...

随机推荐

  1. thinkphp5.0动态配置

    设置配置参数 使用set方法动态设置参数,例如: Config::set('配置参数','配置值'); // 或者使用助手函数 config('配置参数','配置值'); 也可以批量设置,例如: Co ...

  2. Redux学习之解读applyMiddleware源码深入middleware工作机制

    随笔前言 在上一周的学习中,我们熟悉了如何通过redux去管理数据,而在这一节中,我们将一起深入到redux的知识中学习. 首先谈一谈为什么要用到middleware 我们知道在一个简单的数据流场景中 ...

  3. Kuhn-Munkres算法

    KM算法——二分图最大权匹配 我们前面学过了二分图匹配的匈牙利算法.但这种算法是针对没有权值的图来说的. 肯定有人想问,没有权值的用匈牙利算法,哪有权值的图要求最大权或最小权匹配呢?? 这里就引出了我 ...

  4. Eclipse项目红色叹号解决方法

    情况:就是项目出现红色感叹号 解决方法: 对准项目右键选择Build Path → configure build path 点击eclipse项目的configure build path后,在弹出 ...

  5. iOS 9音频应用播放音频之第一个ios9音频实例2

    iOS 9音频应用播放音频之第一个ios9音频实例2 ios9音频应用关联 iOS9音频应用中对于在主视图上添加的视图或控件,在使用它们时必须要与插座变量进行关联.ios9插座变量其实就是为主视图中的 ...

  6. POJ 1509 Glass Beads 后缀自动机 模板 字符串的最小表示

    http://poj.org/problem?id=1509 后缀自动机其实就是一个压缩储存空间时间(对节点重复利用)的储存所有一个字符串所有子串的trie树,如果想不起来长什么样子可以百度一下找个图 ...

  7. Week Four

    2018.12.18 1.[USACO Platinum C] 2.[Gym 102028H] 3.[BZOJ 2750] 4.[BZOJ 3238] 5.[BZOJ 4310] 6.[BZOJ 38 ...

  8. 【尺取法好题】POJ2566-Bound Found

    [题目大意] 给出一个整数列,求一段子序列之和最接近所给出的t.输出该段子序列之和及左右端点. [思路] ……前缀和比较神奇的想法.一般来说,我们必须要保证数列单调性,才能使用尺取法. 预处理出前i个 ...

  9. 【期望DP】BZOJ4008- [HNOI2015]亚瑟王

    题目大意 有\(n\)张卡牌,\(r\)轮游戏.每张卡牌只能用至多一次,每张卡牌被用到的概率为\(p_i\).现在从左往右轮,直到最右一张卡片或者某张卡片被用到.如果某张卡牌被用到,产生\(d_i\) ...

  10. bzoj 3757 树上莫队

    感谢以下文章作者: http://blog.csdn.net/kuribohg/article/details/41458639 http://vfleaking.blog.163.com/blog/ ...