如何仅从TableName#P#pname.ibd格式的.ibd文件恢复已分区的mysql InnoDB表?Chris Calendar的文章http://www.chriscalender.com/?p=28适用于具有单个.ibd文件的非分区表,但是对于分区表,"discard“和"import”步骤会导致"storage engine non this option“错误。
Wes Smith在上面的链接中的一条评论中建议一次导入一个分区的手动步骤,但这对我来说不起作用。如果我尝试遵循他的方法,创建一个未分区的表,移动第一个重命名为TableName.ibd的.ibd文件,然后执行导入,则导入成功,但表中没有行。随后的建议步骤是“重新添加到分区中”,我尝试了一下,因为"alter table TableName partition by range ... (partition pname1 values less than (...) ENGINE=InnoDB)"惊人地将TableName.ibd文件(对应于第一个分区)替换为一个微不足道大小的新TableName#P#pname1.ibd。我尝试这样做时丢失了一个分区的数据。我有大约150个分区需要恢复。
对于如何从.ibd文件中恢复数据有什么建议吗?谢谢。
发布于 2012-09-03 13:27:11
因此,事实证明,在原始帖子的链接处的评论中建议的方法毕竟是有效的。我在"alter table...“中提到的分区的删除上面的步骤是合法的,因为它是在ibdata和日志文件丢失之前在原始表中被故意删除的(但mysql无论如何都不会删除.ibd文件)。恢复过程慢得令人痛苦,但我已经设法编写了脚本,并希望在接下来的几天内完成。
如果您发现自己处于类似的情况,并且有许多分区需要恢复,这里有一些提示。假设您有一个包含100个分区的表TableName。通常,如果这100个分区是通过"create table“语句创建的,那么它们将具有连续的innodb ID,但通常情况可能并非如此,因为分区可能是在创建后添加的。因此,以下是步骤:
1)在上面的博客中使用Calendar的方法找到每个分区对应的innodb ID,如下所示。请注意,此步骤不需要重新启动mysql服务器。只需创建一个不带任何分区的像TableName这样的表,并丢弃它的表空间。然后,将第一个分区的.ibd文件(名称类似于TableName#P#pname1.ibd)作为TableName.ibd移动到数据库目录,并尝试导入它。查看mysql日志(通常为/var/ error.log /mysql/error.log)以查看该分区的innodb是什么。对每个分区重复此步骤(或根据需要),直到拥有文件中所有分区的2元组(innodb_ID_i、partition_boundary_i)。
2)以空的innodb状态启动(停止服务器,删除ibdata和ib_logfile*,重启服务器)。对于上面步骤1中的文件中的每个innodb_ID条目,创建一个类似于TableName的表TableName_i。例如,如果这100个分区对应于ID321、322、...、370、415、416、...464 (每个50个连续ID的两个块),则编写一个脚本来创建320个虚拟表、50个类似TableName的表、45个虚拟表和50个类似TableName的表。
3)对于上面创建的每个TableName_i表,
--do
(i) rename table TableName_i to TableName
(ii) alter table TableName discard tablespace // important to do this step before the next one
(iii) mv TableName#P#pname_i.ibd TableName.ibd // with the appropriate directory prefixes
(iv) alter table TableName import tablespace
(v) alter table partition by range (partition_field) (partition pname_i values less than (partition_boundary_i)) // This is the most and only time consuming step
(vi) rename table TableName to TableName_i // or some other name or just dump it to a file
--repeat 请注意,以上所有步骤都是脚本化的,不需要在任何时候重新启动服务器,除非在步骤2开始时以空的innodb状态启动。在进入下一个步骤之前,请注意检查步骤3中的每个子步骤是否成功,否则后续步骤可能会失败和/或.ibd文件可能会被覆盖。如果可行,请使用步骤3(iii)中的副本,而不是mv。
最后注意:使用percona的恢复工具包使用十六进制编辑可能会稍微简单一些,但这不适用于我使用分区表的情况。我遇到了同样的、看似未解决的问题,在http://www.mysqlperformanceblog.com/2011/05/13/connecting-orphaned-ibd-files/的一条评论中提到了分区表。不过,您的里程可能会有所不同。如果有一种方法可以避免重新创建分区(如上面的步骤3(v) ),那将是非常好和快速的,但我不确定是否有一种方法。
https://stackoverflow.com/questions/12232469
复制相似问题