悟夜叉个人博客 技术专题 利用工具一键对FRM文件进行表结构解析

利用工具一键对FRM文件进行表结构解析

前言:最近遇到了很多数据库还原的问题,借此机会我们来利用两种工具来解析Mysql数据库的“.frm”文件中的表结构内容。当我们在取证过程中,当我们恢复嫌疑人删除的数据库文件,或因其他情况导致Mysql无法启动的时候,我们就要使用新的实例(一般在本地创建)来恢复结构数据。

这里有三种方式,一种是人工的(麻烦),两种是自动的(简单),当然我们选择后者。

# FRM文件简介

在MySQL中,如果我们使用了默认的存储引擎 Innodb 创建一张表,那么在文件夹下面就会出现表名.frm和表名.ibd两个文件,如果我们使用的是 Myisam 存储引擎,那么就会出现三个文件,这里我们给出例子:

[root@ /data/goyasha]#ll
total 580
-rw-rw---- 1 mysql mysql  8586 Apr  3 17:44 a.frm
-rw-rw---- 1 mysql mysql     0 Apr  3 17:44 a.MYD
-rw-rw---- 1 mysql mysql  1024 Apr  3 17:44 a.MYI
-rw-rw---- 1 mysql mysql  8586 Apr  3 17:44 b.frm
-rw-rw---- 1 mysql mysql 98304 Apr  3 17:45 b.ibd
-rw-rw---- 1 mysql mysql    61 Nov 23 09:54 db.opt
-rw-rw---- 1 mysql mysql  8556 Apr 29 21:37 tbl_test_2.frm
-rw-rw---- 1 mysql mysql 98304 Apr 29 21:37 tbl_test_2.ibd
-rw-rw---- 1 mysql mysql  8556 Apr 29 21:33 tbl_test.frm
-rw-rw---- 1 mysql mysql 98304 Apr 29 21:33 tbl_test.ibd
-rw-rw---- 1 mysql mysql  8614 Apr 29 21:40 test.frm
-rw-rw---- 1 mysql mysql 98304 Apr 29 21:43 test.ibd
-rw-rw---- 1 mysql mysql  8666 Apr  2 15:13 unstandard_ins.frm
-rw-rw---- 1 mysql mysql 98304 Apr  3 11:46 unstandard_ins.ibd

其中ibd文件是innodb的表数据文件,而frm文件是innodb的表结构文件,mysiam存储引擎的表中,frm是表结构,MYI文件是索引文件,而MYD文件是数据文件,从这里也可以看出,innodb存储引擎的索引和数据是在一起的,而Myisam存储引擎索引和数据是分开的。

需要注意的是,这个frm文件和ibd文件都是不能直接打开的。

# 表结构长什么样?

我拿我网站的某一张表来做例子:

--
-- 表的结构 `wp_usermeta`
--
CREATE TABLE `wp_usermeta` (
  `umeta_id` bigint(20) UNSIGNED NOT NULL,
  `user_id` bigint(20) UNSIGNED NOT NULL DEFAULT '0',
  `meta_key` varchar(255) COLLATE utf8mb4_unicode_520_ci DEFAULT NULL,
  `meta_value` longtext COLLATE utf8mb4_unicode_520_ci
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci;

# 开始安装Mysqlfrm环境

mysqlfrm 是 mysql utilities 工具集 中的其中之一,且需要在 python2 的环境下运行,安装起来很简单,只需几行代码,复制安装即可。

[root@localhost ~]# wget -c https://downloads.mysql.com/archives/get/p/30/file/mysql-utilities-1.6.5.tar.gz
[root@localhost ~]# tar -xvzf mysql-utilities-1.6.5.tar.gz 
[root@localhost ~]# cd mysql-utilities-1.6.5 
[root@localhost ~]# python setup.py build 
[root@localhost ~]# python setup.py install

# 开始解析FRM文件

首先我们需要把拿到的FRM文件上传到本地测试环境,任意目录都可以,然后直接输入以下命令进行解析。这种模式比较直接,逐个字节分析 frm 文件,尽可能的提取信息。

命令:mysqlfrm –diagnostic /www/ceshi.frm,红色标记的是你的frm文件绝对路径

[root@localhost msql-utilities-1.65]# mysqlfrm --diagnostic /www/ceshi.frm
# WARNING: Cannot generate character set or collation names without the --server option.
# CAUTION: The diagnostic mode is a best-effort parse of the .frm file. As such, it may not identify all of the components of the table correctly. This is especially true for damaged files. It will also not read the default values for the columns and the resulting statement may not be syntactically correct.
# Reading .frm file for /www/2.frm:
# The .frm file is a TABLE.
# CREATE TABLE Statement:

CREATE TABLE `www`.`ceshi` (
  `ID` bigint(20) unsigned NOT NULL AUTO_INCREMENT, 
  `user_login` varchar(240) NOT NULL, 
  `user_pass` varchar(1020) NOT NULL, 
  `user_nicename` varchar(200) NOT NULL, 
  `user_email` varchar(400) NOT NULL, 
  `user_url` varchar(400) NOT NULL, 
  `user_registered` datetime NOT NULL, 
  `user_activation_key` varchar(1020) NOT NULL, 
  `user_status` int(11) NOT NULL, 
  `display_name` varchar(1000) NOT NULL, 
PRIMARY KEY `PRIMARY` (`ID`),
KEY `user_login_key` (`user_login`),
KEY `user_nicename` (`user_nicename`),
KEY `user_email` (`user_email`)
) ENGINE=MyISAM;

#...done.

那么我们的表结构文件就解析出来了。CREATE TABLE `www`.`ceshi`,我们发现数据库名他是按我们路径来生成的。但我们不能进到数据库内去执行这段语句(例如PhpMyAdmin里使用root帐号登陆后展示的是所有的数据库名称,不点到指定数据库内导入,在外面导入),因为他前面带了数据库名。

而且我们还要确定这个 www 的数据库是存在的。除非我们提前在本地环境根目录创建一个跟本地实例(已创建的数据库)名称相同的文件夹(比如库名为 good 就要在根目录创建good文件夹),这个时候我们在去解析他生成的语句就是 CREATE TABLE `good`.`表名` 就可直接导入了!

# dbsake dbsake dbsake,厉害的工具说三遍!

上面的方式还是比较麻烦,最近找到了一个更nb的工具:dbsake

命令:./dbsake frmdump /www/ceshi.frm > /www/ceshi.sql ,红色标记的是你的frm文件绝对路径,蓝色标记的是你输出sql文件的绝对路径。

# 下载安装 dbsake 工具
[root@localhost ~]# curl -s get.dbsake.net > dbsake
[root@localhost ~]# chmod u+x dbsake
# 直接将FRM文件转换成可创建表结构的sql文件
[root@localhost ~]# ./dbsake frmdump /www/ceshi.frm > /www/ceshi.sql

我们来看看输出结果:

--
-- Table structure for table `ceshi`
-- Created with MySQL Version 5.7.34
--

CREATE TABLE `2` (
  `ID` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `user_login` varchar(60) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT '',
  `user_pass` varchar(255) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT '',
  `user_nicename` varchar(50) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT '',
  `user_email` varchar(100) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT '',
  `user_url` varchar(100) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT '',
  `user_registered` datetime NOT NULL DEFAULT '0-00-00 00:00:00',
  `user_activation_key` varchar(255) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT '',
  `user_status` int(11) NOT NULL DEFAULT '0',
  `display_name` varchar(250) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT '',
  PRIMARY KEY (`ID`),
  KEY `user_login_key` (`user_login`),
  KEY `user_nicename` (`user_nicename`),
  KEY `user_email` (`user_email`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci;

注意:这个dbsake解析出的CREATE TABLE后面只有表名,所以导入sql文件的时候是需要先进数据库,再导入。那么这个方法是不是更方便了呢?

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注

评论列表(18)

  1. ALTER TABLE wp_commentmeta IMPORT TABLESPACE;
    [Err] 1812 – Tablespace is missing for table `dc_xpress_com`.`wp_commentmeta`.
    导入表空间报错

  2. alter table songlyric discard tablespace; 这步操作了原本的.idb会自动消失,将需要的.idb拷贝过去以后,执行alter table songlyric import tablespace; 这个以后mysql就挂了,什么原因呢?

  3. ERROR 2013 (HY000): Lost connection to MySQL server during query
    一直报这个错请问博主是怎么解决的?

  4. mysql> desc u_table
    -> ;
    1033 – Incorrect information in file: ‘.\zzdj\u_table.frm’
    这是不是frm文件损坏了???

  5. 我看了你idb恢复的文章,最后执行import的时候提示The storage engine for the table doesn’t support repair,这是为啥,引擎是innodb,能帮我看下吗?

    1. 我的也是,恢复数据的时候报异常
      alter table test import tablespace
      1808 – Schema mismatch (Clustered index validation failed. Because the .cfg file is missing, table definition of the IBD file could be different. Or the data file itself is already corrupted.)

    2. 知道原来的表结构,根据.ibd文件就可以恢复数据,但在我本机上测试的时候发现时间丢失了,有可能是我的mysql是5.7,数据库文件是从5.5中导出来的,我的步骤:
      1)创建表的sql创建表,sql语句末尾按照作者的加上ROW_FORMAT=COMPACT;
      2)alter table test discard tablespace; (在这一步操作以后不需要停止数据库,停止以后mysql反而启动不起来了)
      3)将老的数据的test.ibd放到数据库目录下;
      4)alter table test import tablespace;

联系我们

联系我们

站长QQ/VX:82794

在线咨询: QQ交谈

邮箱: 82794@qq.com

任何技术问题请联系QQ,非特殊行业请勿加微信!龙信小伙伴请联系微信群找我。
关注微信
非商务合作请勿添加

非商务合作请勿添加微信

返回顶部