今天公司一同事使用典型的“UPDATE 不带 WHERE 语句”误操作把数据库中一张极重要数据表 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 后做一次备份;这样的好处是一旦发生“意外”就可以从上一个备份点开始执行,而不是重头执行。请记住在恢复数据的过程中你永远无法预知接下会发生什么事故!

转载于:https://www.cnblogs.com/edwardlost/archive/2011/07/13/2105598.html

利用 MySQL bin-log 恢复数据表相关推荐

  1. mysql用binlog恢复数据_利用mysql的binlog恢复数据

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

  2. 不小心删除数据--利用MySQL的binlog恢复数据

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

  3. MySQL备份和恢复数据表的方法(1)

    备份是最简单的保护数据的方法,本节将介绍多种备份方法.为了得到一个一致的备份,在相关的表上做一个LOCK TABLES,你只需一个读锁定,当你在数据库目录中做文件的一个拷贝时,这允许其他线程继续查询该 ...

  4. mysql重做日志恢复数据_MySQL中重做日志,回滚日志,以及二进制日志的简单总结...

    MySQL中有六种日志文件, 分别是:重做日志(redo log).回滚日志(undo log).二进制日志(binlog).错误日志(errorlog).慢查询日志(slow query log). ...

  5. 如何利用MySQL的binlog恢复误删数据库详解

    文章来源: 学习通http://www.bdgxy.com/ 目录 1 查看当前数据库内容并备份数据库 2 开启bin_log功能 3 模拟误操作(插入3条数据,删除数据库) 4 数据恢复 5 总结 ...

  6. mysql同步binlog_利用MySQL的Binlog实现数据同步与订阅(下)

    利用MySQL的Binlog实现数据同步与订阅(下)​blog.yuanpei.me 终于到这个系列的最后一篇,在前两篇博客中,我们分别了介绍了Binlog的概念和事件总线(EventBus)的实现, ...

  7. myisam数据表根据frm文件恢复数据表

    有时,我们重装mysql时,可能忘记备份数据了, 只留下了之前的mysql下面的data文件夹里的数据, 这时我们应该如何去恢复数据表呢 如果直接将原来的data目录导进现在的mysql,肯定是不行的 ...

  8. java查询mysql装载bean_jsp与javabean链接mysql数据库并查询数据表的简单实例源码

    jsp与javabean链接mysql数据库并查询数据表的简单实例源码.这个简单的实例是给新手学习的,或者一些高手临时忘记怎么使用jsp操作mysql数据库时候查找的,包括了建立mysql数据库连接的 ...

  9. Mysql使用binlog恢复数据解决误操作问题的两种方法

    Mysql使用binlog恢复数据解决误操作问题的两种方法 参考文章: (1)Mysql使用binlog恢复数据解决误操作问题的两种方法 (2)https://www.cnblogs.com/Data ...

  10. 成功解决利用pandas输出DataFrame格式数据表时没有最左边的索引编号(我去,这个问题折腾了我半个多小时)

    成功解决利用pandas输出DataFrame格式数据表时没有最左边的索引编号(我去,这个问题折腾了我半个多小时) 导读:首先,关于这个问题,博主想骂街,经过各种查询,没找到类似问题,然后博主自己不断 ...

最新文章

  1. Python程序设计题解【蓝桥杯官网题库】 DAY5-基础练习
  2. Apache Spark 2.2.0 中文文档 - GraphX Programming Guide | ApacheCN
  3. 初学Python——文件操作第二篇
  4. python 公众号爬虫_python_爬虫_微信公众号抓取
  5. python实战excel_实战python 读写EXCEL表
  6. 海龟交易法则07_如何衡量风险
  7. 惠普:某些 SSD 驱动的寿命只有32,768 小时(3年多),立即更新!
  8. java 父类_java 调用父类的父类
  9. 如何实现SSH断开后 进程仍然在后台运行
  10. 基于Flask框架实现Mock Server
  11. 大众点评字体解密(最新)2020/4/17
  12. Python实现汉字转换拼音
  13. 大话 Redis 数据结构
  14. 机械硬盘 与 固态硬盘SSD
  15. vscode下golang build tags
  16. 【网络】广域网、局域网、城域网
  17. ϵ-greedy Policies
  18. 汉罗塔汉洛塔c++,看不懂ni打我
  19. 利用 画图 快速给图片添加文字
  20. 【c】C语言编程写的一个http下载程序

热门文章

  1. iOS开发那些事-表视图UI设计模式
  2. 编译DirectShow Samples
  3. java栈的回收_JAVA的堆栈和内存、垃圾回收解说
  4. java请求header_java中处理header请求以及跟cookie相关的一些细节
  5. vim全局搜索并跳转
  6. OVS DPDK vhost-user搭建全过程(四十四)
  7. python queue 查询是否在队列中_python队列Queue的详解
  8. 华清远见智能小车视频服务器,华清远见版世界杯足球对抗赛,智能小车C位出道...
  9. 2019全新学习路线图发布
  10. Java B2B2C多用户商城 springcloud架构- common-service 项目构建过程(七)...