加入收藏 | 设为首页 | 会员中心 | 我要投稿 PHP编程网 - 黄冈站长网 (http://www.0713zz.com/)- 数据应用、建站、人体识别、智能机器人、语音技术!
当前位置: 首页 > 服务器 > 安全 > 正文

MySQL如何利用ibd文件恢复数据?

发布时间:2021-01-19 15:23:56 所属栏目:安全 来源:网络整理
导读:副标题#e# 《MySQL如何利用ibd文件恢复数据?》要点: 本文介绍了MySQL如何利用ibd文件恢复数据?,希望对您有用。如果有疑问,可以联系我们。 前言 数据库丢失之痛 磁盘坏道、断电等意外不是常态,但遇上了就足够你“惊心动魄”! 如果是数据库损坏造成的数
副标题[/!--empirenews.page--]

《MySQL如何利用ibd文件恢复数据?》要点:
本文介绍了MySQL如何利用ibd文件恢复数据?,希望对您有用。如果有疑问,可以联系我们。

前言

数据库丢失之痛

磁盘坏道、断电等意外不是常态,但遇上了就足够你“惊心动魄”!

如果是数据库损坏造成的数据丢失,Binlog也不可用了,怎么办?~~

为了在短时间内无损恢复数据以保证业务稳定性,除了利用binlog,我们还修炼了一招新的恢复技能!

正文

还记得我们之前写过的《只需一招,让失控的研发爱上你》吗?前文提到过我们日常使用的比较多的两种数据库恢复方法是:

以上两种方法都可以实现实时性的回档,但是你会认为有了这两种技能就够了吗?

不….!

在线上这种错综复杂的架构中,其实还有很多未知的原因,我们是没法预知的.例如以下这种情况:

因辛勤劳动而折寿的磁盘产生成长坏道,导致数据库损坏.而又刚好损坏了ibdata文件和binlog文件.那么如果还想着以定时备份+binlog恢复的方案就不可能了,难道只能用定点备份回档吗?深思熟虑后,作为一名运维人员,我们是绝对不会在万不得已的情况下实行有损回档,因为这对业务产生太大的影响了,但是除此之外又能怎么办呢?下面我们将要放一门大招!!!

首先检查数据库环境,是否开启了独立表空间,如果已经开启的话,那恭喜你,有很大的机会可以恢复全部数据.我们可以依赖每个数据库目录下的frm和ibd文件来实现数据恢复,一般来说如果使用了InnoDB但没开启独立表空间的话,所有的数据库表信息和元数据都会写入ibdata文件里,这样长久运行的话,ibdata文件会变得越来越大,数据库性能下降.InnoDB提供了开启独立表空间参数,可以让数据独立存放起来,这样子ibdata文件只用于存放一些引擎相关的索引信息,实际的数据写入到独立的frm和ibd文件里.

好,有了frm和ibd文件,我们可以开始尝试数据恢复了,他的过程比binlog还原既惊险又有趣!首先我们来看一下关于ibd和frm的说明:

.frm文件:保存了每个表的元数据,包括表结构的定义等,该文件与数据库引擎无关.

.ibd文件:InnoDB引擎开启了独立表空间(my.ini中配置innodb_file_per_table = 1)产生的存放该表的数据和索引的文件.

我们都知道,对于InnoDB的数据库,如果不把整个数据目录拷贝,只拷贝指定数据库目录到新的实例下,数据库是认不出来的.那么如何根据这两个文件还恢复数据库呢?

恢复思路:

由于ibdata文件上存放了一些关于引擎的索引信息,ibdata文件损坏导致表名索引丢失而无法启动.那么我们可以先把原来旧的整个数据目录改名备份,然后重新初始化数据库生成新的ibdata文件,然后重新创建原有的数据库以及对应的表,最后把备份的表空间id号改为新建的表空间id号(ibdata文件里有每个表唯一的表空间索引id,该id由创建新表的数量依次递增),这样就可以恢复原来的数据库了.

举个例子:

库名:test_restore

表结构:db_struc.sql

表文件:G_RESTORE.ibd、G_RESTORE.frm

1. 创建新库,导入表结构

#mysql -uroot –p**** ?-e “create database test_restore”

#mysql -uroot –p**** ?test_restore < db_struc.sql

2. 查看并修改test_restore库中表在新实例中的id

#vim -b /data/database/mysql/test_restore/G_RESTORE.ibd

直接打开为乱码,转成16进制查看.Vi中执行 ?:%!xxd 转化为16进制.结果为 :

如图所示.G_RESTORE表在mysql数据库中的id为00fe.

修改备份的G_RESTORE.ibd文件.操作同上,注意需先备份.

#cp G_RESTORE.ibd{,_back}

#vim -v G_RESTORE.ibd

将011b修改为00fe?.注意.修改完成后需要在vim中先执行 :%!xxd ?-r

再wq 保存退出文件.不然保存到的是16进制查看的结果.

保存结果如下:

将修改好的G_RESTORE.ibd 替换掉新数据库中的G_RESTORE.ibd文件.

关于ibdata表id的解释:

参考官方文档解释,每个表空间分配了4个字节存储了表空间id信息,最后偏移量地址为38.还有一组预留的表空间id,同样是4个字节,最后偏移量地址为42.

3. 验证并还原mysql数据

关闭mysql.修改my.conf.

innodb_force_recovery=6

innodb_purge_threads=0

启动数据库.如果不修改.数据库会认为G_RESTORE已被损坏.

Select 一下,即可查看到还原结果,但此时插入数据会报错,应尽快将数据dump出来,导回原来的实例中.

导出数据,再导入数据,恢复完毕!

#mysqldump -uroot –p****** test_restore > test_restore.sql

#mysql -uroot –p****** test_restore < test_restore.sql

说明:变更了新的space id后的.ibd表文件,启动数据库后只能认出数据,但不能写入,这是因为原ibdata文件不仅保存了space id索引,还同时保存了一些其它的元数据.为了使元数据补全,所以采取导出、再导入的操作.

(编辑:PHP编程网 - 黄冈站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读