MySQL单表恢复方法

摘要:
虽然已经很久没进行单表恢复了,但是还好步骤都印在脑海中,没有出问题的就恢复完了。言归正传,记录一下单表恢复的步骤和关键点,提醒自己也提醒大家。

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

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

第一步:

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

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

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

第二步:

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

### 使用mysqlbinlog将二进制日志转化为明文SQL日志
mysqlbinlog mysql-bin.000123 > /data1/000123.sql

### 使用linux的grep命令根据“keyword”找到那个引发数据写花的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=0
SET 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=0
SET TIMESTAMP=1386248108/*!*/;
update table tablename set names='xxxx';
# at 20394211#131205 20:55:08 server id 18984603  end_log_pos 20394238     Xid = 92465981
COMMIT/*!*/;
# at 20394238#131205 20:55:10 server id 18984603  end_log_pos 20394308     Query    thread_id=16296017    exec_time=0    error_code=0
SET TIMESTAMP=1386248110/*!*/;
BEGIN 

第三步:

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

### pos位置等于问题SQL begin的pos位置
slave start until master_log_file='mysql-bin.000123',master_log_pos=20393709;

然后跳过这个问题SQL,将同步change到下一个pos位置上,具体使用如下命令

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

从上面两条命令我们看出,第二步得到的两个pos位置很关键。

第四步:

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

### 在主库上执行
rename table tablename to tablename_bak;

然后在还原机上执行dump操作,执行这个操作的使用需要注意,如果表中有中文字符,一定记得需要添加--default-chararter-set参数

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

通过以上命令就可以直接完成dump并导入的操作了,缺点就是不会有一份备份文件生成

第五步:

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

drop table if exists tablename_bak;

数据库恢复是每个DBA必备的技能,需要熟练掌握,希望度过这篇文章的同学们都可以轻车熟路的进行恢复操作。

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

免责声明:文章转载自《MySQL单表恢复方法》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇GUI线程安全详解(一)常用ANSI控制码及其相关内容总结(转)下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

mysql8新特性

1. 默认字符集由latin1变为utf8mb4 在8.0版本之前,默认字符集为latin1,utf8指向的是utf8mb3,8.0版本默认字符集为utf8mb4,utf8默认指向的也是utf8mb4。注:在Percona Server 8.0.15版本上测试,utf8仍然指向的是utf8mb3,与官方文档有出入。 2. MyISAM系统表全部换成In...

MySQL、MongoDB、Redis 数据库之间的区别

NoSQL 的全称是 Not Only SQL,也可以理解非关系型的数据库,是一种新型的革命式的数据库设计方式,不过它不是为了取代传统的关系型数据库而被设计的,它们分别代表了不同的数据库设计思路。 MongoDB:它是一个内存数据库,数据都是放在内存里面的。对数据的操作大部分都在内存中,但MongoDB并不是单纯的内存数据库。MongoDB 是由 C++...

mysql——导入文本文件——用mysqlimport命令

CMD进入DOS窗口执行: mysqldump -u root -p123 -T C:\Users\del\Desktop see cr01 --fields-terminated-by=',' --lines-terminated-by='\r\n' mysqlimport -u root -p123 see C:\Users\del\Deskto...

ROS学习之日志消息

ROS学习之日志消息 ROS日志系统的核心思想,就是使程序生成一些简短的文本字符流,这些字符流便是日志消息。 0.1严重级别        ROS中,日志消息分为五个不同的严重级别,也可简称为严重性或者级别。按照严重性程度递增,这些级别有       DEBUG       INFO       WARN       ERROR       FATAL 0...

FPGA--UART串口通信

一,串口相关知识 UART 通信 UART 首先将接收到的并行数据转换成串行数据来传输。消息帧从一个低位起始位开始,后面是 7 个或 8 个数据位,一个可用的奇偶位和一个或几个高位停止位。接收器发现开始位时它就知道数据准备发送,并尝试与发送器时钟频率同步。如果选择了奇偶校验,UART 就在数据位后面加上奇偶位。奇偶位可用来帮助错误校验。在接收过程中, UA...

PHP站内搜索:多关键字、加亮显示

一、SQL语句中的模糊查找       主要通过LIKE(不区分大小写)关键字实现模糊查找。LIKE条件一般用在指定搜索某字段的时候, 通过"%"或者" _" 通配符的作用实现模糊查找功能,通配符可以在字段前面也可以在后面或前后都有。只通过LIKE是无法实现模糊查找的,因此通配符的作用不可忽略。下面是三个实例:搜索以PHP开头:SELECT * FROM ...