`
cfyme
  • 浏览: 262728 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

利用 MySQL bin-log 恢复数据表

 
阅读更多

转载地址:http://www.cnblogs.com/edwardlost/archive/2011/07/13/2105598.html

如果误操作把数据库中一张极重要数据表 player 给“做掉了”,还算幸运的是该数据库每3个月会完整备份一次,最近一次的备份点为6月30日,再加上 bin-log 保留了30天的数据,可以根据这两份数据还原数据表的内容。方法看上去非常简单清晰,但是具体执行起来还是遇到了很多问题,下面整理了一些关键问题,以备以后灾难再发生时可供参考。

 

在处理 bin-log 前首先要把二进制的文件转换成文本文件,方法:

/data/mysql/bin/mysqlbinlog mysql-bin.001468 > mysql-bin.001468.txt


由于一开始我们想当然认为针对 player 表的更新 SQL 都是单行语句,所以就直接使用 grep 进行行级的提取,这种简单做法也为我们后面的恢复失败埋下了“地雷”。

 

先看一下文本格式 bin-log 的记录格式:

# at 7473
#110630 11:56:05 server id 1  end_log_pos 7612  Query   thread_id=6     exec_time=0     error_code=0
SET TIMESTAMP=1309406165/*!*/;
UPDATE ssmatch
.young_league_match_7 SET status='playing' WHERE mid=699617
/*!*/;

 

显而易见,正确的提取方法应该是:
1. 读取一行数据,如果行首字符为'#'则跳过,否则执行第2步;
2. 检测行尾字符是否为';',如果不是则继续读下一行直到行尾字符为';',所有读取的行构成一条 SQL 语句,执行第3步;
3. 清空读取的行缓存,如果已到文件尾则结束,否则跳到第1步循环处理;

 

下面接着说使用 grep 过滤行数据,不能够使用 insert、update、delete、replace 关键词去做严格的匹配,这样很容易漏掉SQL,因为不同人写的 SQL语句格式差异很大。正确的做法是采用“排除法”,即:先使用表名作为关键词进行grep,然后再通过一些关键词滤掉可能误选的SQL。比如:出错的数据表名为 player,而 bin-log 记录的数据库中还有 player_position、young_player 等表,那么我们就需要过滤包含这些数据表名的SQL。只根据数据表名进行过滤还不行,还要根据数据表的字段名,比如:staff表中包含 judge_player_ability 字段,那么对staff表执行的更新操作也会被提取出来,所以需要检查数据库中所有数据表的字段,将包含 player 关键词的字段名全部过滤点。

 

下面是实际提取player表更新SQL语句的命令:

cat mysql-bin.001468.txt | grep -i \"player\" |grep -v \"player_position\|player_league\|young\|match_info\|tactics\|player_buddy\|player_champion\|player_cup\|player_friend\|staff\|match_report\|setpieces_nid\|old_player_ca\|new_player_ca\" > mysql-bin.001468.player


最后说一下上面提到的“地雷”问题,我们在数据重跑进度达到80%的时候遇到 bin-log 中下面格式的update语句:

UPDATE player SET /* 此粗省略更新字段内容 ... */
WHERE nid = 1111

“它换行了!!!WHERE语句在第2行!!!”,悲催啊,上面的行级提取方法将完整的UPDATE语句截断了,重跑执行的是“不带 WHERE 的 UPDATE”!!!一下回到解放前,这下只能重头开始再执行一遍!在重跑前还需要将这种“病毒”语句清理掉。

 

所以,除非你非常肯定确定一定不会出现多行SQL语句,否则都一定要使用上面的正确做法提取SQL。

 

一条宝贵的经验:在恢复数据的过程中一定要做阶段备份,比如在重跑 SQL 时发生错误导致中断,那么可以先把该时间点的数据表复制一份,然后再从中断点往后继续执行;更好的做法是一开始就按阶段进行数据恢复,比如有30个 bin-log 文件需要重跑,那么可以每跑5~10个 bin-log 后做一次备份;这样的好处是一旦发生“意外”就可以从上一个备份点开始执行,而不是重头执行。请记住在恢复数据的过程中你永远无法预知接下会发生什么事故!

 

分享到:
评论

相关推荐

    MySQL bin-log 日志清理方式

    MySQL bin-log 日志清理方式 MySQL bin-log 日志清理方式

    mysql将bin-log日志文件转为sql文件的方法

    mysql打开bin-log日志后,mysql数据库的非查询操作会将记录保存到bin-log文件中。一般bin-log日志文件不能打开查看的,需要用到mysql的工具进行。假设/mysql/data/目录中存放着二进制文件mysql-bin.000011。需要将...

    开启bin-log日志mysql报错的解决方法

    代码如下:ERROR 1418 (HY000): This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration and binary logging is enabled (you *might* want to use the less safe log_bin_trust_...

    mysql-connector-java-5.1.25, mysql 5.7.31亲测有效

    mysql-connector-java-5.1.25, mysql 5.7.31亲测有效,如无法使用可解压后压缩为zip

    mysql-connector-java-8.0.21.rar 数据库连接依赖最新版

    mysql-connector-java-8.0.21.rar 数据库连接依赖最新版 适用于mysql 8.0.21最新版的

    mysql如何利用binlog进行数据恢复详解

    MySQL Binary Log也就是常说的bin-log, ,是mysql执行改动产生的二进制日志文件,其主要作用有两个: * 数据回复 * 主从数据库。用于slave端执行增删改,保持与master同步。 binlog基本配置和格式 binlog基本配置 ...

    mysql-connector-java-5.7 驱动程序 jar 包.txt

    mysql57驱动jar包

    mysql-connector-java-8.0.24

    mysql jar包 版本8.0.24

    开启mysql-Binlog

    开启mysql-binlog操作 binlog日志用于记录所有更新了数据或者已经潜在更新了数据的所有语句。语句以“事件”的形式保存,它描述数据更改。当我们因为某种原因导致数据库出现故障时,就可以利用binlog日志来挽回...

    使用bin-log日志还原数据库的例子

    4、查看mysql日志:mysqlbinlog mysql-bin.000001mysqlbinlog mysql-bin.000006 > /root/bbx.log 5、使用新的binlog日志:(更新数据库日志) 代码如下:方法一:[root@bogon mysql]# mysqladmin -uroot -p flush-...

    mysql binlog

    MySql BinLog BinLog 开启 配置 ...log_bin_basename /var/log/mysql/mysql-bin //注释 :文件昵称前缀 log_bin_index /var/log/mysql/mysql-bin.index //注释 :索引 log_bin_trust_function_crea

    mysql-8.0.20-macos10.15-x86_64.tar.gz

    -log-error=/usr/local/mysql/data/mysqld.log --pid-file=/usr/local/mysql/data/192.168.0.103.pid --socket=/usr/local/mysql/data/mysql.sock --port=3306 使用 之前的记住的 Wt#GeUu_q2oJ的密码,测试mysql的...

    开发JAR包集合-log4j lucene wsdl poi proxool xml ojdbc

    mysql-connector-java-5.1.8-bin.jar ojdbc14.jar poi-3.6-20091214.jar proxool-0.9.1.jar proxool-cglib.jar slf4j-api-1.6.1.jar slf4j-simple-1.6.1.jar wsdl4j-1.6.2.jar wss4j-1.5.8.jar wstx-asl-3.2.9.jar ...

    MySQL JDBC驱动

    包括三个版本:mysql-connector-java-5.0.3-bin.jar,mysql-connector-java-5.0.4-bin.jar,mysql-connector-java-5.0.8-bin.jar

    mysql5.7操作文档大全

    Mysql根据ibd文件恢复数据 40 9.1 创建新数据表,和源数据表一致 40 9.2 删除新数据表的表空间 40 9.3 将待恢复的<table_name>.ibd文件copy到目标数据库文件夹下,并修改文件权限 40 9.4 导入表空间 41 十. 根据frm...

    mysql-5.5.14.tar.gz

    /usr/local/mysql/bin/mysqld_safe --user=mysql & /usr/local/mysql/bin/mysql Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 2 Server version: 5.5.14-log ...

    mysql-java8-tomcat8

    chown mysql:mysql /var/lib/mysql -R 10\启动MySQL systemctl start mysqld systemctl stop mysqld //停止 systemctl restart mysqld //重启 systemctl enable mysqld //设定mysql服务随着系统启动自动...

    MySQL5.6.24-win32

    log-error = D:\DB\MySQL\log\mysql_error.log port = 3306 ------栗子举完了--------- 更改好后记得保存!!! ***************第一步END******************** ###最佳办法是将mysql安装目录\bin填写到path路径中...

Global site tag (gtag.js) - Google Analytics