zoukankan      html  css  js  c++  java
  • mysql的数据恢复

    转载自: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/,$ ^ ;/;/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 ;

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

  • 相关阅读:
    代理 XP”组件已作为此服务器安全配置的一部分被关闭。系统管理员可以使用 sp_configure 来启用“代理 XP”。
    sql 操作常用操作语句 新增、修改字段等
    easyui 日期控件清空值
    jQuery文件上传插件jQuery Upload File 有上传进度条
    js中文乱码怎么解决【转】
    [转]SqlSever2005 一千万条以上记录分页数据库优化经验总结【索引优化 + 代码优化】一周搞定
    SqlBulkCopy批量添加数据
    常用正则表达式
    查询每张表的大小
    Jquery里的特定小技巧
  • 原文地址:https://www.cnblogs.com/grimm/p/5068221.html
Copyright © 2011-2022 走看看