2024年2月18日发(作者:)
利用frm 和 idb文件批量还原数据
最近碰到一个问题,一个平时不怎么用数据库在一次搬机器过程中弄挂了,然后在重启过程中不小心把ibdata给弄坏了。于是无奈只能通过frm和idb文件来做数据恢复。因为是整个库的数据有问题,因此在这过程中写了一些脚本来帮助恢复。
下面是这次操作的过程:
首先说明,本方案只适用于 innodb_file_per_table = 1 这种情况下的做数据恢复。
下面是用来说明恢复案例的环境:
原数据库数据文件的位置: /data/dbdata
库名称: user
新库的用户名、密码:root/111111
新库的数据文件位置:/data/newdata
1、首先做好frm和idb文件的备份,并准备一个全新的MySQL环境,至于为什么要全新的,稍后就会明白。
2、通过frm文件导出表结构
如果你本身就有创建数据的schema的sql脚本,这一步可以略过。
a、首先创建user库;
> create database user;
b、接下来需要在user库创建原库的frm对应的表,这一步可通过 create_init_【/iamxhu/devops_tools/blob/master/mysql/recovery/create_init_】生成创建表的脚本。具体使用方法参加文件中的说明。
$ ./create_init_ /data/dbdata/user root 111111 user
运行上面的脚本后,会生成三个文件:create_tmp_,discard_,import_。在这一步只需要将create_tmp_导入到mysql中。
> mysql -uroot -p user < create_tmp_
这样表就都创建好了。
c、 关闭mysql,修改 在[mysqld]段中增加如下配置:
innodb_force_recovery = 6
d、将需要恢复的frm文件替换新的库是的frm文件
$ cp /data/dbdata/user/*.frm /data/newdata/user/
e、重启mysql 这时登录就可以看到恢复好的表结构了。
3、恢复idb中的数据
a、首先需要找出原来的idb中的space id,可通过下面的方法完成/iamxhu/devops_tools/blob/master/mysql/recovery/find_mysql_ 。
$ ./find_mysql_ /data/dbdata/user root 111111 user
脚本将会生成一个文件:export_table_。 这个文件主要是用来导出新生成表的建表语句create_。生成的create_需要再手动处理一下,删除开头的表名。
因为针对一个库,可能其中表的space id不一定是连续的,因此第一步生成的表不能直接使用需要重新建表。create_会根据space id的之间的差值,自动插入一些临时表来填充space id。
b、注释掉innodb_force_recovery = 6 重启mysql继续下面的操作。
c、找出最小的space id,在MySQL中填充好space id。
这一步需要注意,不要填多了,否则又要重新弄一个新的MySQL环境了。最好分两部做,先留100个space id,在生成完第一批表之后查看一下最后生成的表的space id再填充后面的space id。
填充space id可以使用 fill_table_ 脚本来完成。用法如下:
$./fill_table_ 100 root 111111
d、填充完成后,执行导入表结构。
如下操作:
$ mysql -uroot -p user < create_
e、执行discard_脚本,做discard tablespace操作。
$ ./discard_
f、将原来的idb文件拷贝到现在的user库目录下,并修改权限
$ chown /data/newdata/user/*.idb
g、执行import_
$./import_
h、在中将innodb_force_recovery = 6 的注释打开,然后重启MySQL。
这时候可以登录进去看看数据是不是都存在了。如果一切都OK的话,接下来可以执行export_table_脚本,导出数据了。 然后你也可以直接dump出sql文件。
本文作者胡星,现任职于华强北商城,原文转自博客:/


发布评论