记一次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的数据恢复的主要内容,如果未能解决你的问题,请参考以下文章