记一次mysql的数据恢复

Posted shitian-net

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了记一次mysql的数据恢复相关的知识,希望对你有一定的参考价值。

数据库版本:mysql5.7

操作系统:CentOS 7.7

引:我之前一直使用 Sql Server ,最近自己创业,为了省点钱,用了MySql

某天,我悠然的写着代码,调着BUG。我们的运营大佬突然跟我反馈了一个线上版本的问题:

技术图片

说是数据突然不见了,我没怎么在意,心里在想,八成是客户自己把数据删了?? (PS:开发那么多年大部分灵异的反馈都是客户操作失误)

然而过了两分钟,运营大佬又反馈另一个客户也出现同样问题

技术图片

 

 

 此时我感觉不妙,但一时也想不起是什么问题,几分钟后,我突然.....想起了三天前把数据从 Sql Server 数据迁移到 MySql时写的那个测试脚本

技术图片

我把它挂在了MVC Home/Index 路由下了。后来我发现navicat可以很方便的导入数据,就把它给忘了...忘了....忘了...,然后更新到了线上环境,今天突然不知道哪个没事干的兄弟直接访问了一下我的项目域名。默认跳转Home/Index ,结果悲剧了,数据恢复到了三天前...,万幸的是我这个脚本只写了一个表,也就是说,只有一张表出了点问题。

当务之急是赶紧恢复数据。Sql Server数据恢复我有经验,一句脚本就可以恢复到某个时间点,特方便。但MySql没恢复过数据【抓虾】

在恢复之前,我先做了一个操作,把需要恢复的表主键自增起始值拔高,避免恢复期间新增加的数据跟老数据主键冲突。

然后上网一搜,找到了一个类似于sqlserver的解决方案:binlog 日志恢复。以下是相关命令

1、链接数据库,查询日志开启状态(ON开启)(如果你的数据库没有开启这个,估计用不了下面的方法了,万幸我开启了)

mysql -u root -p
MySql>show variables like ‘log_%‘;

(看到有开启日志之后,我心已经放下半个,心里想这不就跟sqlserver一样,选个前几分钟的时间点,恢复那张表不就行了)

2、查询日志操作(看看已经记录了哪些日志)

MySql>show logs;

3、查看master状态(看现在哪个日志文件在用)

MySql>show master status;

4、刷新日志(让数据库日志从一个新的文件开始记录,老的我要用来做恢复)

flush logs;

5、导出整个库某个时间点之前的操作到sql(不要直接跟着操作哦,后面有坑)

mysqlbinlog /www/server/data/mysql-bin.000004(这个是日志文件的地址) --skip-gtids=true --stop-datetime=‘2020-07-14 17:35:30‘  --database=数据库名称 > /www/server/202007142245.sql

6、执行恢复 

mysql -uroot -p密码 数据库名 < /www/server/202007142241upd.sql;

OK,我感觉已经大功告成,胜利在握了。

结果报错,说数据库已经存在...难道我的姿势不对?我得先删除数据库再操作???

好吧,备份当前数据库,删掉它。继续

mysql -uroot -p密码 数据库名 < /www/server/202007142241upd.sql;
继续报错,数据库不存在.....你想怎样....

于是我把脚本文件直接下载下来(600多M...),查看了一下内容,找到create database xxxxx 的时间,把第5步的导出脚本改成创建数据库之后

mysqlbinlog /www/server/data/mysql-bin.000004 --skip-gtids=true --start-datetime  "2020-07-10 17:38:46" --stop-datetime=‘2020-07-14 17:35:30‘  --database=数据库名 > /www/server/202007142245.sql

再继续第6步

mysql -uroot -p密码 数据库名 < /www/server/202007142245upd.sql;

还是报错,表xxxx已存在.....,我后面又改了几次方案,又发现主键等其他报错...此时我已是提心吊胆,颤颤巍巍,如履薄冰,哆哆嗦嗦

终于在第n个小时时候我找到了解决办法,如下

创建一个新的数据库,把导出的脚本文件(202007142245upd.sql)中有关于老数据库的名称 全部替换成 新的数据库名称 (这里用了notepad++),然后继续执行第6步(注意:数据库名称也换成新的)

mysql -uroot -p密码 新数据库名 < /www/server/202007142245upd.sql;

等了十几分钟,终于全程没报错的执行完毕。

接下来就简单多了,因为我只有一张表数据被恢复到之前的状态,而且恢复数据期间表的主键有拔高,我直接将新库里面那张渠道表所有数据导入老库替换就大功告成。

但是如果你出问题的数据多,而且表数据会不断变化,那么你只能先停止你的应用。关闭所有可能导致数据库变化的链接。然后再进行恢复操作了。

 

以上

参考文章:

https://juejin.im/post/5d39839d6fb9a07ee74322ff#heading-1

https://blog.51cto.com/lvnian/1699627

以上是关于记一次mysql的数据恢复的主要内容,如果未能解决你的问题,请参考以下文章

记一次血淋淋的MySQL崩溃修复案例

记一次线上MySQL数据库死锁问题

记一次MySQL崩溃修复案例,再也不用删库跑路了

记一次MySQL崩溃修复案例,再也不用删库跑路了

记一次MySQL崩溃修复案例,再也不用删库跑路了

记一次mysql数据恢复