shunhua's blog

mysql通过.ibd和.frm文件恢复数据

2019-12-17

数据库存储的数据实际上也是存储在文件里的,此类文件只能mysql能读取。

Myisam 引擎:

xxx.frm 表结构文件
xxx.MYD 数据文件
xxx.MYI 索引文件

Innodb 引擎:

xxx.ibd 数据和索引文件
xxx.frm 表结构文件

此篇环境为Lnmp集成环境下的mysql
在/etc/my.conf datadir = /usr/local/var/mysql/

简写主要步骤:
1.将原先的.ibd文件与原先的.frm文件解除绑定

alter table 表名 discard tablespace;

2.停掉服务,新的.ibd文件覆盖旧的.ibd文件,再开启服务

3.将新的.ibd文件与.frm文件发生联系

alter table 表名 import tablespace;

类似这种单个表操作,若表很多 可简单分批处理[.ibd、.frm同级目录执行]
安装 mysql-utilities

yum -y install mysql-utilities

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?php
$files = glob("*.ibd");
$discardTablespace = '';
$importTablespace = '';
$createTable = '';
foreach ($files as $key => $value) {
$discardTablespace .= "ALTER TABLE `{$value}` DISCARD TABLESPACE;\n";
$importTablespace .= "ALTER TABLE `{$value}` IMPORT TABLESPACE;\n";
//恢复表建表语句
$value = substr($value, 0, -3).'frm';
$shell = 'mysqlfrm --server=root:数据库密码@localhost:3306 '.$value.' --port=3309 --user=root | tail -n +12';
$output = shell_exec($shell);
$lineCount = substr_count($output, "\n");
$arr = explode("\n", $output);
$arrCount = count($arr);
$arr = array_slice($arr, 0, $arrCount-3);
$createTable .= join("\n", $arr).";\n\n";
}
file_put_contents('discard_tablespace.sql', $discardTablespace); //用于删除表空间
file_put_contents('import_tablespace.sql', $importTablespace); //用于导入新的表空间
file_put_contents('structure.sql', $createTable); //用于建表结构

php index.php &

生成的文件中可能存在[表名+.ibd]的类表名,可手动修改。

由于版本库的原因可能存在文件为空(全是分号)

mysqlfrm –diagnostic ./ >> structure.sql

执行完后 检查下sql文件中可能存在(varchar(1020))等字符问题 可手动修改完善

source structure.sql

此时执行完后 会生成表结构。

执行discard_tablespace.sql 解除旧的绑定关系

source discard_tablespace.sql

新的.ibd文件覆盖旧的后 执行导入新的关系

source import_tablespace.sql

使用支付宝打赏
使用微信打赏

欢迎点击上方按钮对我打赏,谢谢你给我吃糖果