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

剖析MySQL InnoDB记录格式以从原始磁盘恢复,mysql,innodb,file-format,raw-data,Mysql,Innodb,File Format,Raw Data,我有一个mysql数据库存储在一个USB拇指驱动器上,它不可修复地丢失了它的文件分配表。因此,我无法将ibdata1文件作为一个整体。但是,我可以找到使用十六进制编辑器使用的记录页 所有的数据都在那里,但我必须自己读取每条记录,并将新的SQL语句回放到从6个月的备份恢复的数据库中 因为我有备份,所以我知道表的结构。可以在新数据库中找到一条记录,我知道它大致相当于一小块二进制数据。但是,我很难确定记录的确切起始位置并解码记录数据 表的CREATE语句是: 创建表ExpenseTransaction

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

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

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

表的CREATE语句是: 创建表ExpenseTransactions IDEExpenseTransactions int11非空自动增量, TransactionDate日期时间不为空, DollarAmount浮点值默认为空, PoundAmount浮点值默认为空, 位置varchar255默认为空, MinorCategory int11不为空, 注释varchar255默认为空, 周期性位1不为空默认值b'0', 估计位1不为空默认值b'0', 主键IdeExpenseTransactions, 关键小范畴小范畴 ENGINE=InnoDB AUTO_INCREMENT=4687默认字符集=utf8;

干净的记录如下所示: “2924”,“2013-11-01 00:00:00”,“60”,空,“乔治”,“66”,“草坪维护”,“1”,“0”

下一个是与此记录关联的十六进制字节。我很确定要重新创建记录,字节数比需要的要多,但我已经标记了我认为是id字段的内容,以尝试提供一些参考点。 10 06 02 00 01 70 00 41 80 00 00 0B 6C 00 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 65 6F 72 67 65 80 00 00 42 4C 61 77 6E 20 4D 61 69 6E 74 65 6E 61 6 E 63 65 01 00


我可以很容易地找出字符串,并且我可以找出组成MinorCategory的4个字节。最后2个字节应表示2位值。剩下的就更难了。

有问题的记录被正确识别,根据我的博客文章,下面是它的解码方式:

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

优秀的我读过你的帖子,但我看不到其中的细微差别。谢谢47 65 6F 72 67 65 Location=George的字符串长度在哪里?您正在编写的工具已经为innodb写了undrop,帮助从ddrescue转储中从我的原始磁盘数据中提取页面。这至少让我不必用手去追踪页面。谢谢你的链接!和德雷斯库的一个好的举动。即将死亡的磁盘可能无法再次读取。若要使用流式解析器查找InnoDB页面,那个么也要检查c_解析器。它将从页面中获取记录。请参阅c_解析器上的示例,对于这项任务来说,它绝对是很棒的。它会弹出一个标签分隔的列表,列出我目前缺少的所有东西。谢谢你的使用链接!