正休息的时候一个电话将我的睡意完全打散,“开发童鞋写update SQL的时候忘了加where条件了”,相信每一个DBA同学听到这个消息的时候都有骂街的冲动吧。万幸只是单表写花了,而不是哪位大神在DB里面drop table玩。虽然已经很久没进行单表恢复了,但是还好步骤都印在脑海中,没有出问题的就恢复完了。

  言归正传,记录一下单表恢复的步骤和关键点,提醒自己也提醒大家。

第一步:

  找一台性能比较高的服务器作为还原机,从备份池中将最近的一次备份恢复到这台还原机上。当然这个前提是你有备份,且备份是可用的。(什么? 你告诉我没有做备份,那么同学你可以洗洗睡了,准备享受自由的空气吧。)

  注意:这个时候不要启动同步,务必保持不同步状态。

  ps:多说一嘴,对于DBA来说,备份是最重要的一个环节,不但要有,还要定期检查备份是否是可用的,这是DBA的必要素质之一。

第二步:

  联系那个犯错的开发同学要错误的SQL语句和时间点,然后从主库的binlog中找到这条SQL的执行点。具体操作举例如下

### 使用mysqlbinlog将二进制日志转化为明文SQL日志mysqlbinlog mysql-bin.000123 > /data1/000123.sql### 使用linux的grep命令根据“key word”找到那个引发数据写花的SQL所在的位置cat 000123.sql |grep -C 10 'key word' --color### 标红色的是问题SQL,及这条SQL开始的时间点,及下一条SQL的开始时间点,这2个pos位置非常重要# at 20393709#131205 20:55:08 server id 18984603 end_log_pos 20393779 Query thread_id=16296016 exec_time=0 error_code=0SET TIMESTAMP=1386248108/*!*/;BEGIN/*!*/;# at 20393779#131205 20:55:08 server id 18984603 end_log_pos 20394211 Query thread_id=16296016 exec_time=0 error_code=0SET TIMESTAMP=1386248108/*!*/;update table tablename set names='xxxx';# at 20394211#131205 20:55:08 server id 18984603 end_log_pos 20394238 Xid = 92465981COMMIT/*!*/;# at 20394238#131205 20:55:10 server id 18984603 end_log_pos 20394308 Query thread_id=16296017 exec_time=0 error_code=0SET TIMESTAMP=1386248110/*!*/;BEGIN

  根据第二步得到的pos位置,启动同步关系,但是需要停止到问题SQL之前的pos位置上,具体使用如下命令

### pos位置等于问题SQL begin的pos位置slave start until master_log_file='mysql-bin.000123',master_log_pos=20393709;
### pos位置等于问题SQL commit之后的pos位置change master to master_log_file='mysql-bin.000123',master_log_pos=20394238;

第四步:

  在主库上将写花的表改名,其目的有二个,其一,停止对这个表的写入(当然这对业务会有一定的影响,会出现一段时间内的写入失败报警,需要提前和业务部门联系好),其二,一旦恢复失败,至少还有一个写花的表存在,可以很快的恢复成我们恢复操作之前的状态。

### 在主库上执行rename table tablename to tablename_bak;
mysqldump -uusername -ppassword -S/tmp/mysql.sock dbname tablename --opt> tablename.sql
### 可以选择登陆mysql之后source tablename.sql;### 也可以在cmd界面mysql -uusername -ppassword -S/tmp/mysql.sock < tablename.sql
### 快速的方法可以按照如下操作,在还原机上的命令mysql -uusername -ppassword -S /tmp/mysql.sock dbname tablename | mysql -uusername -ppassowrd -hhost -Pport

第五步:

  基本DBA的事情就没有了,这时候就需要告诉开发同学恢复完毕,进行应用测试及数据正确性效验了。如果一切都没有问题之后,我们需要将刚才rename的表drop掉,整个恢复操作就算大功告成了。

drop table if exists tablename_bak;

  ps:这个操作,最好一万年都不要用一次就最好了。

更多相关文章

  1. MySQL系列多表连接查询92及99语法示例详解教程
  2. Linux下MYSQL 5.7 找回root密码的问题(亲测可用)
  3. MySQL 什么时候使用INNER JOIN 或 LEFT JOIN
  4. 发现 developer.android.com 官网的一个单词错误:
  5. 背部如何画好?动漫人物背部画法步骤
  6. android 命令(adb shell)进入指定模拟器或设备
  7. Android--WebView+HTML+Javascript
  8. android从服务器下载文件(php+apache+win7+MySql)
  9. Android绘制简单折线图的步骤

随机推荐

  1. Java - 检查所有行中现有文本的.txt
  2. JavaScript进行简单的随即验证码生成(适合
  3. Android推荐跟踪不支持谷歌播放
  4. OOP面向对象编程(一)-------方法的重载
  5. 树形结构的处理——组合模式(四)
  6. springMVC使用html视图配置详解
  7. 80端口占用异常解决方法java.net.BindExc
  8. Java中的数据类型
  9. 基于Java的应用程序的GUI测试工具
  10. java.lang.NoSuchMethodException:在strut