系统环境:Centos7.2
架构:Mysql主从
数据库:Mysql5.7.9
说明:公司正式环境,不小心drop一张表,由于开始了binlog日志,所以我们将采用最近一次全备 + mysql-binlog日志的方式进行恢复,我的数据备份机制为“8小时/天”,每天3次,下面来说说具体操作步骤。
一、思路
1.1 记下出问题的时间点,我是2018.09.11 12:59:00左右出的问题
1.2 那么根据时间点找到最近一份mysql-bin-000030的日志,我们将用它来进行恢复
二、具体操作
2.1 拿到xxx.sql数据库的2018.9.11 08:00:00早上的全库备份,以早8:00至13:00(要包括出问题的时间点)所有binlog日志
数据库文件
mysql-bin-0000xx日志文件
2.2 找1台安装有mysql数据库的服务器,将备份的数据库导出,我们要在此基础上采用“binlog”进行恢复
2.3 因为binlog在windows下不能直接读,使用"mysqlbinlog --no-defaults mysql-bin.000039 >39.txt "将binlog日志重定向至39.txt文本,将39.txt下载到自己windows电脑,如果有多个日志,建议重复本操作,为什么下载到本地?因为binlog日志都很大,在windows上面使用crtl+f,可以很方便的根据时间点进行查找。
2.4 将binlog日志转换为mysql可识别语句
方法一:mysqlbinlog --no-defaults -d DB_name --start-datetime='2018-09-11 8:54:40' --stop-datetime='2018-09-11 12:59:10' mysql-bin.000032 >temp20180911.sql
方法二:mysqlbinlog --no-defaults --database=edu --start-datetime='2018-09-11 10:48:53' --stop-datetime='2018-09-11 10:49:24' mysql-bin.000032 >temp20180911.sql
说明:将起始时间点为"2018-09-11 8:54:40",结束时间点为“2018-09-11 12:59:10”,这段时间内的"mysql-bin-000032"的binlog日志导出到临时脚本文件"temp20180911.sql"中,用于在mysql数据库里面使用source temp20180911.sql 进行恢复
--database ##与"-d"作用相同,用于指定数据
-d ##与“database”作用相同,用于指定数据库
--start-datetime ##起始时间点
--stop-datetime ##结束时间点
--start-position ##起始位置
--stop-position ##结束位置
2.5 在mysql里进行恢复
source temp20180911.sql ; ##将我们刚刚创建的临时脚本在此处进行恢复
2.6 查看已恢复的数据数量
select count (*) from xxx where ' create_datetime > 2018-09-11 08:00:00 ' ;
三、细分时间段,导出某个时间段的内容,采用“truncate”方法,清空表数据,但保留表结构
3.1 使用2.4的方法,将binlog日志导出至某个临时文件
3.2 在mysql>truncate xxx_table ;
3.3 source temp20180911_10:50.sql ;
3.4 查看这个时间段的表数据
select count (*) from xxx where ' create_datetime > 2018-09-11 08:00:00 ' ;
四、直接采用binlog日志进行恢复
mysqlbinlog --no-defaults --start-datetime='2018-09-11 8:54:40' --stop-datetime='2018-09-11 12:59:10' /root/mysql-bin.000032 | mysql -uroot -p
说明:将起始点与结束点之间的binlog日志,直接用于恢复(此种方法在非主从同步的机器上报错),建议采用方案二。
五、在恢复过程中所采的坑
Type0:在恢复之前要将binlog日志里面的DROP TABLE语句删除,切记切记!!
Type0:在恢复之前要将binlog日志里面的DROP TABLE语句删除,切记切记!!
Type0:在恢复之前要将binlog日志里面的DROP TABLE语句删除,切记切记!!
Type1:错误:ERROR 1032 (HY000) at line 324: Can't find record in ‘tablename'
解决方案: 在执行的时候加上“--no-defaults”
Type2:主从同步错误
开启主从同步 mysql> start slave;
vim /etc/my.cnf
[mysqld]
slave-skip-errors = all
Type3:主键重复问题
根据报错的行数和binlog日志和时间点进行对比,进行过滤并采用本文细分时间段解决此问题
Type4:解决MySql Error Code: 2006 – MySQL 服务器已离线 错误
vim /etc/my.cnf
[mysqld]
max_allowed_packet = 100M
interactive_timeout = 28800000 ##单位:秒
wait_timeout = 28800000 ##单位:秒
Type5:binlog日志权限不足
解决方案:增加权限
六、额外插曲
##在已备份的数据库中导出单个表方案
解决方案:A和B表之间的表的区间,就等于取A表
awk '/-- Table structure for table `table_A`/,/-- Table structure for table `table_B`/{print}' bak_edu.sql >>temp.sql
说明:将A表重定向到一个临时表“temp.sql”,用户后期恢复这张A表