解析MySQL InnoDB记录格式以从原始磁盘恢复

时间:2015-05-22 21:09:42

标签: mysql innodb file-format raw-data

我有一个存储在USB拇指驱动器上的mysql数据库,它无法挽回地丢失了它的文件分配表。因此,我无法从整体上看到ibdata1文件。但是,我可以找到使用十六进制编辑器使用的记录页面。

所有数据都在那里,但我必须自己阅读每条记录并将新的SQL语句回放到从6个月的备份中恢复的数据库。

因为我有备份,所以我知道表结构。并且可以在新数据库中找到一条记录,我知道该记录大致相当于一小块二进制数据。但是,我无法确定记录的确切位置并解码记录数据。

表的CREATE语句是: CREATE TABLE ExpenseTransactions ( idExpenseTransactions int(11) NOT NULL AUTO_INCREMENT, TransactionDate datetime NOT NULL, DollarAmount float DEFAULT NULL, PoundAmount float DEFAULT NULL, Location varchar(255) DEFAULT NULL, MinorCategory int(11) NOT NULL, Comment varchar(255) DEFAULT NULL, Recurring bit(1) NOT NULL DEFAULT b'0', Estimate bit(1) NOT NULL DEFAULT b'0', PRIMARY KEY (idExpenseTransactions), KEY MinorCategory (MinorCategory) ) ENGINE=InnoDB AUTO_INCREMENT=4687 DEFAULT CHARSET=utf8;

干净的记录如下所示: ExpenseTransactions

接下来是与此记录关联的十六进制字节。我非常肯定有更多的字节来重新创建记录,但我已经标记了我认为是id字段以试图给出一些参考点。 idExpenseTransactions

我可以很容易地理解字符串,我可以选出构成MinorCategory的4个字节。最后2个字节应代表2位值。其余的更难。

1 个答案:

答案 0 :(得分:0)

相关记录已正确识别,并且根据我的博客文章The physical structure of records in InnoDB,以下是其解码方式:

Header:
10                          Length of Comment = 16 bytes
06                          Length of Location = 6 bytes
02                          Nullable field bitmap (PoundAmount = NULL)
00                          Info flags and number of records owned
01 70                       Heap number and record type
00 41                       Offset to next record = +65 bytes

Record:
80 00 0B 6C                 idExpenseTransactions = 2924
00 00 00 00 07 05           TRX_ID
86 00 00 01 4A 0E B1        ROLL_PTR
80 00 12 4F 23 1F C1 40     TransactionDate = "2013-11-01 00:00:00"
00 00 70 42                 DollarAmount = 60.0
                            (No data, PoundAmount = NULL)
47 65 6F 72 67 65           Location = "George"
80 00 00 42                 MinorCategory = 66
4C 61 77 6E 20 4D 61 69     Comment = "Lawn Maintenance"
6E 74 65 6E 61 6E 63 65     (Comment continues...)
01                          Recurring = 1
00                          Estimate = 0