通过.frm 和.ibd 批量恢复mysql数据

本文介绍如何使用.frm和.ibd文件批量恢复MySQL InnoDB引擎的数据。包括数据库和表的创建、表结构的重建、数据文件的导入等步骤。

前置

首先,只有InnoDB引擎的数据库才需要这样恢复,myisam不需要这么麻烦,只要数据文件存在直接复制过去就可以。

其次,mysql数据库必须是按表存放数据的,默认不是,但是大家生产肯定是按分表设置的吧,如果不是,则无法这样恢复数据。mysql.ini的设置为 innodb_file_per_table = 1。

.frm文件是mysql表结构定义文件,使用mysql-utilities中的mysqlfrm来将其转换成mysql的create语句,来重建表结构

.ibd文件存了每个表的元数据,包括表结构的定义等。就知道是用这个来恢复数据就行

工具

mysql-utilities https://downloads.mysql.com/archives/utilities/

恢复过程

建数据库

以一道网站重构题为例

题目给了网站源码和mysql的数据库文件

首先找到网站源码里对数据库连接的config文件,将其参数改为我们自己建立的数据库。

我们要按照它的db.opt来创建对应的数据库

default-character-set=utf8mb4
default-collation=utf8mb4_general_ci

数据库名:quzhen

用户:quzhen

密码:quzhen

注意:用phpstudy创建数据库要用innodb引擎

image-20221010075806804

建表

先将.frm文件的文件名提取出来,他们的文件名对应着一个数据表

dir /b /t >frmname.txt

dir命令https://blog.youkuaiyun.com/weixin_41905135/article/details/124881754

然后利用notepad++的功能将.frm文件剪切出来,然后再去掉后缀

image-20221009223605478

<think> 我们已知用户的需求是“从ibd文件恢复MySQL数据”,并且用户给出了三个引用内容。我们需要结合这些引用,提供详细的恢复方法。 引用[1]提供了两种情况:知道表结构不知道表结构。 引用[2]提到使用frm文件(在MySQL 8.0之前,表结构存储在.frm文件中)ibd文件恢复,但注意MySQL 8.0不再使用.frm文件。 引用[3]提到了在Ubuntu下利用.ibd文件恢复数据,其中给出了一个批量拼接删除表空间语句的方法。 考虑到用户可能使用不同版本的MySQL(尤其是8.0版本变化较大),我们需要分情况说明。 恢复方法主要分为两种情况: 1. 已知表结构(即可以创建与原表结构完全相同的表) 2. 未知表结构(需要使用工具从ibd文件中提取表结构数据) 步骤: 情况一:已知表结构(适用于MySQL 5.6及以上版本,使用独立表空间) 步骤1: 创建同名数据库(如果需要)原表结构完全相同的表(注意使用相同的存储引擎InnoDB)。 步骤2: 删除新表的表空间(使数据库断开与ibd文件的关联) 执行:`ALTER TABLE 表名 DISCARD TABLESPACE;` 步骤3: 将待恢复ibd文件复制到新数据库数据目录下,并确保文件权限正确(通常属于mysql用户)。 步骤4: 导入表空间: 执行:`ALTER TABLE 表名 IMPORT TABLESPACE;` 注意:如果ibd文件来自另一个数据库实例,可能需要先执行`FLUSH TABLES ... FOR EXPORT`(在源数据库)来生成一个.cfg文件以兼容不同服务器的表空间,但如果没有.cfg文件,也可以尝试直接导入,但可能遇到问题(如引用[2]提到的CFG文件缺失错误)。在MySQL 8.0中,如果没有.cfg文件,而两个数据库的ROW_FORMAT相同,且没有使用一些特定功能(如表压缩、加密等),则可能成功。 情况二:未知表结构(需要使用工具) 方法1: 使用ibd2sql工具(如引用[1]所述) 步骤1: 安装Python3(如果需要) 步骤2: 下载ibd2sql工具(注意:该工具在GitHub上,地址为https://github.com/ddcw/ibd2sql) 步骤3: 使用该工具解析ibd文件,生成建表语句插入数据的SQL脚本。 命令示例:`python3 main.py /path/to/table.ibd --ddl --sql` 这会输出两个部分:建表语句(DDL)插入数据的SQL(INSERT语句)。 步骤4: 将生成的SQL脚本在目标数据库中执行,即可恢复表结构数据。 方法2: 对于MySQL 8.0之前的版本,如果有.frm文件(表结构文件),可以使用mysqlfrm工具(如引用[2]所述)从frm文件获取表结构,然后再结合ibd文件恢复数据。 步骤1: 安装mysql-utilities(包含mysqlfrm工具)所需的运行环境(如C++ 2013运行时) 步骤2: 使用mysqlfrm工具从frm文件生成建表语句 命令示例:`mysqlfrm --server=user:password@localhost:port --port=临时端口 frm文件路径 --diagnostic > 输出sql文件` 注意:这里需要启动一个临时MySQL服务(通过--port指定一个端口),该工具会连接到这个临时服务来解析frm文件。 步骤3: 根据生成的建表语句创建表。 步骤4: 然后按照情况一的步骤2-4导入ibd文件。 注意事项: 1. 权限问题:确保复制的ibd文件的所有者权限与MySQL数据目录中的其他文件一致(通常属于mysql用户)。在Linux下,可以使用`chown``chmod`命令修改。 2. CFG文件缺失:在导入表空间时,如果没有.cfg文件(该文件在导出表空间时生成,用于记录表结构的元数据),可能会报错。解决办法: - 如果是同一版本的MySQL,且表结构完全相同,可以尝试跳过该错误(在MySQL 5.7/8.0中,有时即使没有.cfg文件也能导入成功)。 - 如果导入失败,则可能需要使用工具(如ibd2sql)直接导出数据为SQL语句再导入。 3. 自增主键冲突:在恢复数据后,插入新数据时可能会遇到自增主键冲突,这是因为原表中可能有自增主键的值已经很大,而新表的自增主键从1开始。解决方法: - 在恢复数据后,执行以下语句调整自增主键的值(假设表名为t,自增列名为id): `ALTER TABLE t AUTO_INCREMENT = (SELECT MAX(id)+1 FROM t);` 详细步骤(已知表结构): 1. 创建新数据库新表(结构与原表一致) 2. 在目标数据库执行:`ALTER TABLE 表名 DISCARD TABLESPACE;` (此时会删除新表对应的ibd文件) 3. 将待恢复ibd文件复制到目标数据库数据目录下(覆盖或放入) 4. 确保ibd文件权限正确(MySQL进程有读取权限) 5. 在目标数据库执行:`ALTER TABLE 表名 IMPORT TABLESPACE;` 如果导入表空间时报错,可以尝试以下步骤(MySQL 8.0): - 在复制ibd文件之前,在源数据库(如果还在)对表执行:`FLUSH TABLES 表名 FOR EXPORT;` 这样会生成一个.cfg文件,将此.cfg文件ibd文件一起复制到目标数据库数据目录,然后在目标数据库执行`ALTER TABLE ... IMPORT TABLESPACE;`,最后在源数据库执行`UNLOCK TABLES;`(如果源数据库还在运行)。 如果上述方法都失败了,则建议使用ibd2sql等工具直接导出SQL数据。 注意:在恢复过程中,务必先备份所有原始文件,避免操作失误导致数据无法恢复。 根据以上内容,我们为用户整理一个清晰的回答。 </think> 从 IBD 文件恢复 MySQL 数据的方法主要分为**已知表结构****未知表结构**两种情况,具体操作步骤如下: --- ### 一、已知表结构(直接挂载 IBD 文件) 1. **创建相同结构的表** 在目标数据库中新建同名表,确保表结构与原表**完全一致**(包括字段、索引、存储引擎等): ```sql CREATE TABLE 表名 (...字段定义) ENGINE=InnoDB; ``` 2. **卸载新表的表空间** 断开新表与默认 IBD 文件的关联: ```sql ALTER TABLE 表名 DISCARD TABLESPACE; ``` 3. **替换 IBD 文件** - 将待恢复的 `.ibd` 文件复制到 MySQL 的 `data/数据库名/` 目录 - 确保文件权限归属 MySQL 用户(如 `chown mysql:mysql 表名.ibd`) 4. **导入表空间** ```sql ALTER TABLE 表名 IMPORT TABLESPACE; ``` > **注意**:若提示 CFG 文件缺失错误(常见于跨服务器恢复),见下文[处理方法](#cfg)。 --- ### 二、未知表结构(工具解析 IBD) #### 方法 1:使用 `ibd2sql` 工具(推荐) 1. **安装依赖** ```bash yum install -y python3 # Ubuntu/Debian 用 apt install python3 wget https://github.com/ddcw/ibd2sql/archive/refs/heads/main.zip unzip main.zip && cd ibd2sql-main ``` 2. **解析表结构与数据** ```bash python3 main.py /路径/表名.ibd --ddl --sql > 恢复脚本.sql ``` - `--ddl`:生成建表语句 - `--sql`:生成 INSERT 数据语句 3. **执行恢复脚本** 在 MySQL 中导入生成的 SQL 文件: ```bash mysql -u用户 -p 数据库名 < 恢复脚本.sql ``` #### 方法 2:使用 `mysqlfrm`(适用于 MySQL 5.7 及更早版本) 1. **获取表结构** 若有 `.frm` 文件(旧版 MySQL 表结构文件): ```bash mysqlfrm --server=用户名:密码@localhost:3306 --port=3307 /路径/表名.frm --diagnostic > 表结构.sql ``` 2. **创建表并导入数据** - 执行生成的 `表结构.sql` 建表 - 按[已知表结构步骤](#一已知表结构直接挂载-ibd-文件)挂载 IBD 文件 --- ### 常见问题处理 <a id="cfg"></a> 1. **报错 `Cannot find CFG 文件`** - **原因**:跨实例恢复时缺少元数据文件 - **解决**: 1. 在源服务器(若可用)执行: ```sql FLUSH TABLES 表名 FOR EXPORT; -- 生成 .cfg 文件 ``` 2. 复制 `.cfg` `.ibd` 文件到目标服务器 3. 目标服务器执行 `ALTER TABLE ... IMPORT TABLESPACE;` 2. **自增主键冲突** 恢复后执行以下 SQL 重置自增值: ```sql ALTER TABLE 表名 AUTO_INCREMENT = (SELECT MAX(主键字段)+1 FROM 表名); ``` 3. **文件权限问题** ```bash chown mysql:mysql /var/lib/mysql/数据库名/表名.ibd # 修改文件属主 chmod 660 /var/lib/mysql/数据库名/表名.ibd # 修正文件权限 ``` --- ### 关键注意事项 1. **MySQL 版本兼容性** - MySQL 8.0+ 不再使用 `.frm` 文件,优先选 `ibd2sql` - 跨大版本恢复时(如 5.7→8.0),建议用工具导出 SQL 再导入 2. **数据一致性验证** 恢复后立即执行: ```sql CHECK TABLE 表名; -- 检查表是否损坏 ``` 3. **操作前备份** **务必**复制原始 IBD 文件到安全位置,避免操作失误导致数据永久丢失。 > 参考工具文档:[ibd2sql GitHub](https://github.com/ddcw/ibd2sql) [^1]|[mysqlfrm 使用指南](https://dev.mysql.com/doc/mysql-utilities/1.6/en/mysqlfrm.html) [^2] ---
评论 11
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

v2ish1yan

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值