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

Dissecting MySQL InnoDB record format to restore from raw disk

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

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

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

table 的 CREATE 语句是: 创建 TABLE <code>ExpenseTransactions ( idExpenseTransactions int(11) NOT NULL AUTO_INCREMENT, TransactionDate 日期时间不为空, DollarAmount 浮动默认为空, PoundAmount 浮动默认为空, Location varchar(255) 默认为空, MinorCategory int(11) 不为空, Comment varchar(255) 默认为空, Recurring bit(1) NOT NULL DEFAULT b'0', Estimate bit(1) NOT NULL DEFAULT b'0', 主键(idExpenseTransactions), 键 MinorCategory (MinorCategory) ) 引擎=InnoDB AUTO_INCREMENT=4687 默认字符集=utf8;

干净的记录如下所示: '2924', '2013-11-01 00:00:00', '60', NULL, 'George', '66', 'Lawn Maintenance', '1', '0'

接下来是与该记录关联的十六进制字节。我很确定有比重新创建记录所需的更多字节,但我已经标记了我认为是 id 字段以尝试提供一些参考点。 10 06 02 00 01 70 00 41 <b>80 00 0B 6C</b> 00 00 00 00 07 05 86 00 00 01 4A 0E B1 80 00 12 4F 23 1F C1 40 00 00 70 42 6F 47 65 72 67 65 80 00 00 42 4C 61 77 6E 20 4D 61 69 6E 74 65 6E 61 6E 63 65 01 00

我可以很容易地理解字符串,并且可以挑选出构成 MinorCategory 的 4 个字节。最后 2 个字节应表示 2 位值。剩下的就比较难了。

相关记录已正确识别,根据我的博客 post 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