从InnoDB文件挽救MySQL数据
--James Qi 2010年5月26日 (三) 13:35 (CST)
上周MySQL服务器崩溃后,我们以为正常mysqldump出来的.sql备份文件又出现错误,导致无法从备份恢复全部数据,而此时我们已经将innodb的log和ibdata文件删除,只好将file-per-table下整个目录打包保存下来设法恢复。
咨询了几位业内技术高手,都是innodb文件如果删除了日志就没有办法恢复了,网上一般的说法也都是如此。要是这样的话,就真惨了,积累了多少年的网站数据全部丢失,需要从头开始,这简直无法想象!
后来偶然在另外一台服务器上找到了当时做主从MySQL服务器试验的时候留下的从服务器数据,但最后一次同步日志是2009年10月21日的,如果用这个数据的话,将使查号吧网站退回半年的数据,此后我们做过的MediaWiki升级、用户添加的几万条数据、几位管理员日常做的巡检工作、每月更新的号段数据、多语言增加的链接,还有我日积月累的一些改进等,将会全部都废掉。所以不到万不得已,不会使用找到的这个半年期的数据,这是一个数据保存底线。
挽救数据需要时间,还在前段时间试验过“用MediaWiki的FileCache来脱离数据库运行网站”,故障当天晚上设置为缓存文件起作用,这样还可以让浏览者查看以前存在的页面,只是无法查询和留言。先也只有用这个办法对付起来,然后尽快设法恢复数据库。
在网上找到这篇老外写的文章:Recovering an InnoDB table from only an .ibd file.从文章内容来看,正是我们需要的!这里面说的主要是将.ibd文件的table space ID与新设立MySQL数据库中的table space ID对应上,其中说到了两种办法:创建多个工作表、16进制修改.ibd文件,我们采取了第二种方式。这个办法用起来还是有效的,上个周末用这种方式恢复出来了38个表中的33个。不过还剩下5个表却遇到这样的报错:
070206 9:31:42 InnoDB: Error: page 63 log sequence number 0 4317619 InnoDB: is in the future! Current system log sequence number 0 8204.
查了资料,说是因为.ibd中数据的log sequence number大于新设立MySQL数据库的对应号码,一个解决的办法是专门不断进行数据库操作,让这个log sequence number迅速增加到.ibd文件该号码的后面去。我们同事专门调试了循环插入、删除语句,进行了优化尝试,最快能让log sequence number增加100万/秒,不过因为我们以前服务器积累了几年,这个数据达到惊人的4000多亿,所以需要5天以上的时间来运行才能达到。好像没有办法让这个增加更快,只有等待几天时间后再尝试了,只是希望log sequence number这个数字问题解决后,不再报其它错就好(前面还遇到page 0以外的page中table space ID报错、校验和报错等)。
另外,还在Google Code中找到一个专门的工具:innodb-tools: Data Recovery Toolkit for InnoDB,就是用于从innodb文件中恢复数据的,需要进行编译、运行程序来使用,我们同事用这个工具恢复了1个表还比较顺利,然后人工清除里面的明显垃圾数据(例如:字段全为空或者数字特别大等),只需要导入数据库就可以。但继续设法恢复其它表的时候,遇到这个工具不支持blob、binary、varbinary等字段定义的问题,现在还没有解决,正在查找资料和尝试。
这次数据丢失不仅影响用户访问,也耽误了我们的好多时间来进行挽救工作,已经过去一周时间了还没有完全恢复,希望接下来的一周时间内能解决就谢天谢地了!
标签:MySQL、InnoDB。 |
相关内容:
|