转自https://blog.csdn.net/hi__study/article/details/53489672
一次恢复数据库表结构和数据的实战,仅以此贴作为记录。
由于,前几天我们使用的数据库被入侵(顺便鄙视一下安全管理人员),数据库中的表都显示不存在(仅剩一个黑客自建的—-qq_xxxxx的表,但物理文件都在,例如:.frm、.ibd文件等)。因此,产生了这次恢复表结构和表数据的实战。以下开始记述:
我们对数据库很多知识都不太了解,而像这种恢复数据的工作也没有做过,因此首先百度了一下.frm和.ibd文件是做什么的,见下:
MySQL中.frm文件:保存了每个表的元数据,包括表结构的定义等,该文件与数据库引擎无关。
MySQL中.ibd文件:InnoDB引擎开启了独立表空间(my.ini中配置innodb_file_per_table = 1)产生的存放该表的数据和索引的文件。
接着,百度了一下如何用.frm和.ibd文件恢复数据库的方法。
1、首先,恢复数据库表结构,以我本地数据库中t_user表为例,其结构如下:
CREATE TABLE t_user (
id INT(11) NOT NULL AUTO_INCREMENT,
create_date DATETIME NULL DEFAULT NULL,
email VARCHAR(255) NULL DEFAULT NULL,
nickname VARCHAR(255) NULL DEFAULT NULL,
password VARCHAR(255) NOT NULL,
phone VARCHAR(255) NULL DEFAULT NULL,
status INT(11) NOT NULL,
username VARCHAR(255) NOT NULL,
PRIMARY KEY (id)
)
COLLATE=‘utf8_general_ci’
ENGINE=InnoDB
AUTO_INCREMENT=2;
①、创建一个新数据库,然后创建一个和需要恢复的表的引擎相同的同名表(即引擎为InnoDB的t_user表,其结构无所谓,可以只有一个字段),如下:
以上,我在新建的mytest数据库中创建了一个引擎为InnoDB的只有一个字段a的t_user表。
②、使用net stop mysql关闭数据库服务,然后用需要恢复的t_user.frm覆盖这个新建的mytest数据库的t_user表的物理文件t_user.frm,接着对配置文件(my.ini)设置innodb_force_recovery = 6,然后使用net start mysql启动服务,并在控制台进入mytest库中,使用desc t_user查看该表结构,如下:表不存在
③,此时,我们查看../mysql/data下的log文件,可以看到如下:
以上,应该是说mytest下t_user只定义了一列,但MySQL中有8列。
④,使用net stop mysql停掉服务,然后在配置文件my.ini中将innodb_force_recovery = 6注释掉(#或;均可),再net start mysql启动服务。接着,将mytest下t_user表删掉(drop掉),再新建一个8列字段的t_user表,如下:字段随意
⑤、继续重复②中的操作,使用desc t_user即可获取到t_user的表结构(使用mysqldump导出即可),如下:
2、用t_user.ibd文件恢复t_user表的数据
①、停掉数据库服务,将innodb_force_recovery = 6注释掉,然后启动数据库服务(若启动中出现1067错误,可以尝试删除data文件夹下ibdata1、ib_logfile0、ib_logfile1即可)并删除mytest下t_user表,并使用新导出的表结构创建t_user表,如下:
②、由于.ibd文件含有tablespace id,因此我们将需要恢复数据的t_user.ibd的tablespace id改为新创建的t_user.ibd的tablespace id,如下:使用了winHex
需要恢复数据的t_user.id的tablespace id:
新创建的t_user.ibd的tablespace id:
修改后的带数据的t_user.ibd如下:
③、停掉数据库服务,使用修改tablespace id的t_user.ibd文件覆盖mytest库下的t_user.ibd文件,并且将配置文件中innodb_force_recovery = 6去掉注释,进入mytest库内,使用select * from t_user查看数据,获取到数据如下:
④使用mysqldump导出表结构和数据即可。
至此,一次使用.frm和.ibd文件恢复数据库数据的演示结束。
注意:最好重新配置一个空的MySQL来进行恢复操作,这样不会影响到MySQL下别的数据库,本例中使用的是MySQL 5.6.24版。
评论 (0)