MySQL5.7版本的数据库表恢复实际操作
背景
原来使用的数据库在Linux系统中,在某一次数据迁移时出现了问题导致数据库内表无法查看到表和相关数据。索性在Mysql的data路径下面还存在表的 .ibd文件和 .frm文件,所以本次数据恢复过程将利用存在的.ibd文件和 .frm文件来进行。
过程
因为Linux系统的指令行实在不习惯,所以本次恢复过程是在将文件从Linux系统的服务器中移出来之后,在Windows系统中进行
准备工具
系统环境 :1、Mysql5.7.31(5.7.*的版本均可以,因为服务器上是31,所以这里我们也选择使用31的版本号)
2、Navicat(Mysql的可视化操作工具,可以直观的看到表的结构和数据内容)
正式开始
1、恢复表结构
先确认Mysql是出于运行状态,正在运行显示已经启动,此前没启动就会提示启动成功。
C:\Users\Administrator>net start mysql
1.1、创建一个新的数据库
首先我们先创建一个新的库,需要确认库的字符集和排序规则(如下图)与原本的库一致。如果忘记了,可以在先前MySQL的data路径下面找到对应的库名称路径进去之后找到一个叫db.opt的文件,即可确认。
(注:这一步可以不进行,但是考虑到我们原本使用的数据库可能含有其他表,为了防止后续操作失误,导致其他的表结构损坏得不偿失,所以推荐在新的库下面进行操作。)
default-character-set=utf8
default-collation=utf8_general_ci
1.1-1指令行创建数据库
当然本步骤也可以在mysql命令行内进行,这里demo是我创建数据库的名称,最后别忘了加上; 。
mysql> CREATE DATABASE demo
-> DEFAULT CHARACTER SET utf8
-> DEFAULT COLLATE utf8_unicode_ci;
1.2、创建一个新的表
在我们不知道原先表的结构有哪些字段的时候,我们先随意创建一张表内容可以随便,省事的话创建一个id即可。
点击保存之后,我们可以在Navicat里看到demo库下面有一个新的表user(如果没有,请关闭数据库再重新打开或者在对象界面刷新后再看看)
1.2-1 指令行创建新表
mysql>use demo;
mysql>create table user(id int);
1.3、覆盖表结构
打开MySQL存储数据的data文件找到对应的数据库名称的文件夹。(同时这个路径下面有个.err文件,这个很重要后续可能会用到)
注: 如果找不到data路径,可以去MySQL的安装路径下面找到my.ini配置文件,里面对应有一个datadir配置,就是data所在的路径位置。
进入demo文件夹,可以看到我们刚创建的user表的.ibd文件和.frm文件。
将我们此前从服务器上获取的.frm文件将当前的.frm文件进行覆盖。
C:\Users\Administrator>net stop mysql
重新运行启动MySQL服务,并进入到mysql中,此时我们会得到提示
ERROR 1146 (42S02): Table 'demo.user' doesn't exist
C:\Users\Administrator>net start mysql
MySQL 服务正在启动 .
MySQL 服务已经启动成功。
mysql> use demo;
Database changed
mysql> desc user;
ERROR 1146 (42S02): Table 'demo.user' doesn't exist
此时我们找到data目录下面的一个.err后缀的文件,进行阅读找到最新的ERROR数据,我们可以得知是因为我们在最开始创建的user表,我们只创建了一个字段,而实际是有10条,所以返回了错误。
那么,我们就根据这个提示,先将此前创建的user先删除,重新创建一个含有10的字段的数据库(10个字段没有要求,为了方便省事,这里创建了id1,id2,id3,id4,id5...id10)。
重复此前的操作,将服务器里取出的frm文件对新的frm文件进行覆盖操作。(覆盖操作同样记得要关闭MySQL服务哦!)同时,再开启MySQL服务前,找到my.ini配置文件,再最下方添加一行新的配置信息,innodb_force_recovery = 6 。这条配置的意思是,当前表只读,无法进行表修改,如果后续需要进行表修改操作,还需要将这条配置注释掉或者去掉再重启服务才行。
innodb_force_recovery = 6
再次启动MySQL服务,进入到库中,使用 desc user; 指令进行查看表(此时只能看)。
mysql> desc user;
+-----------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------+--------------+------+-----+---------+----------------+
| id | bigint(20) | NO | PRI | NULL | auto_increment |
| account | varchar(255) | YES | | NULL | |
| password | varchar(255) | YES | | NULL | |
| person_charge | varchar(255) | YES | | NULL | |
| tel | varchar(255) | YES | | NULL | |
| add_time | datetime | YES | | NULL | |
| last_login_time | datetime | YES | | NULL | |
| is_delete | int(1) | YES | | NULL | |
| parking_id | int(11) | YES | | NULL | |
| department_id | int(11) | YES | | NULL | |
+-----------------+--------------+------+-----+---------+----------------+
10 rows in set, 1 warning (0.01 sec)
此时,我们就能查看到表的结构了。接下来,我们可以选择自己手段去创建一张一摸一样的表。当然,此时我们可以通过navicat去拉取sql语句。在navicat界面,选中我们要的表,右键找到转储SQL文件-仅结构… 就可以直接获取到sql文件啦。
再重新导入到新的sql语句时,出现了错误,经过排查发现是缺少了一个主键,所以我们手动添加一个语句将id字段设置为主键,重新运行表结构就恢复了。
2、恢复数据
相比表结构恢复,数据恢复相对就简单很多了。在创建表的时候,我们发现data下面会同时生产frm文件和ibd文件,frm文件是用来存储表结构的,而ibd文件就是用来存储表数据的。
2.1取消空间关联关系
表数据不能像表结构那样仅仅只是读取,更多的还是需要进行增删改这些写入操作,所以不能通过文件覆盖的形式去更新,需要我们先把之前创建时自带的初始ibd文件先进行取消空间关联关系。
mysql> alter table user discard tablespace;
2.2重新建立空间关联关系
在执行完之后,我们发现原本的ibd文件已经被移除了。此时,我们再将先前的ibd文件复制进去,进行重新管关联操作。
mysql> alter table user import tablespace;
结束
到这里,数据库表的恢复工作就结束了。整体过程还是比较简单的,需要注意的时过程中有多次需要我们关闭MySQL服务的操作,以防止恢复过程中,出现异常。还有需要我们修改my.ini配置,在修改完配置后,也需要我们在保存完配置文件后要及时重启服务,保证我们的配置内容能够及时生效。
本次学习记录参考内容