上周接了个活儿,客户那边MySQL数据库突然起不来了,报错信息里明晃晃写着“InnoDB: Corruption of the InnoDB tablespace”,一看就是ibdata1文件出问题了。客户急得团团转,说库里有五年的订单数据,备份倒是有一份,但那是三天前的,这三天的数据要是丢了,得赔不少钱。我一边安抚他,一边心里也打鼓——ibdata1这玩意儿,是InnoDB引擎的核心表空间文件,它要是坏了,整个库都瘫在那儿,数据能不能完整捞回来,真得看运气和手法。

先说说ibdata1到底是啥。它存的不光是表数据,还有事务日志、回滚段、数据字典这些关键信息。MySQL在初始化的时候,会在数据目录下生成这个文件,默认大小是12M,但只要你开了innodbfilepertable,那新的表都会单独建表空间文件,ibdata1主要就剩下系统表空间和共享信息了。问题在于,很多老库、或者没开那个参数的库,数据全挤在ibdata1里,文件动辄几十上百G,一旦损坏,那感觉就跟家里水表爆了一样——阀门关不上,水漫金山。
我处理的第一步,永远是先备份现场。别急着动手,先停掉MySQL服务,然后把整个数据目录复制一份到安全位置,包括ibdata1、iblogfile0、iblogfile1,还有所有.frm和.ibd文件。这一步看着简单,但很多人一着急就跳过,结果改坏了连回头路都没有。复制的时候注意磁盘空间够不够,几百G的目录复制起来得花点时间,但磨刀不误砍柴工。备份完,再检查一下MySQL的配置文件,看看innodbfilepertable是不是开着,这决定了后续恢复方案是走全量重导还是能分表处理。
第二步,得判断损坏程度。把备份目录里的ibdata1单独拿出来,用strings命令扫一下,看看里面还能不能读出表结构信息。有些情况下,ibdata1只是索引页坏了,数据页还健在,那还有救。更常见的情况是,数据字典损坏,MySQL启动时报“Cannot open data dictionary”,这时候你得换个思路——用“--innodbforcerecovery”参数启动MySQL。这个参数是官方留给紧急恢复的钥匙,取值从1到6,数字越大越激进。我一般从1开始试,能启动就赶紧用mysqldump把数据导出来,导完再重建库。这里有个坑,force recovery模式下,数据库只能读不能写,而且尽量别跑太复杂的查询,能导一张表是一张表。
如果force recovery也搞不定,那就得动真格的了——用工具直接解析.ibd文件。开源工具里有个叫“nbfc”的,全称是“No Backup For Corruption”,专治各种InnoDB文件损坏。它能绕过ibdata1,直接从各表的.ibd文件里提取数据,生成SQL语句或者CSV格式。我用过几次,效果还真不错,但前提是那些.ibd文件本身没坏,只是系统表空间挂了。还有商业工具像“Percona Data Recovery Tool for InnoDB”,功能更全,支持损坏页跳过、自动拼接记录,就是收费,但数据真值那个价的时候,花点钱不算啥。
第三步,就是重建数据库了。无论前面是导出了SQL还是CSV,思路都一样——建一个全新的MySQL实例,把参数调对,尤其是innodbfileper_table必须开着,这样以后每张表独立表空间,单个文件坏了不影响全局。然后把导出的数据导进去,再恢复原来用户权限、存储过程、触发器这些附属品。这一步最耗时间,但也是最稳的。客户那三天的数据,我用force recovery从旧ibdata1里硬抠出来了一部分,另外一部分从binlog里补,总算凑齐了。整个过程折腾了七个多小时,但看到数据完整落库,客户眼眶都红了。
写这些,不是显摆我多能修,而是想提醒各位,ibdata1损坏这事儿,真不是小概率事件。机房断电、磁盘坏道、误删文件、MySQL异常关闭,哪个都能把它搞坏。我见过太多人,平时不备份,出了事才四处求人,要么找不着工具,要么操作不当把数据二次破坏。你哪怕每天全备一次,binlog开起来,出事后最多丢几分钟的数据,修起来也轻松得多。备份这东西,就像保险,用的时候嫌贵,出事的时候嫌少。
再说个细节,恢复完数据库后,别急着切回生产。先跑一轮完整性校验,比如用CHECK TABLE检查每张表,再看看日志里有没有报错,然后做一次全量备份,确认无误后再切换。我那个客户,恢复完第二天早上又找我了,说有个报表查询特别慢,一查原来是恢复过程中没建索引。所以重建时,索引、外键、自增属性这些都得跟着建齐,不然功能是恢复了,性能又成了新问题。
收个尾,ibdata1文件损坏,别慌,也别乱动。按照备份现场、评估损坏、重建数据的路子走,大多数情况下都能把数据库完整捞回来。但说一千道一万,最好的恢复方案永远是“用不上恢复方案”——好好做备份、开binlog、定期演练恢复流程,比啥都强。数据这东西,平时看着只是硬盘上的一堆字节,真丢了才明白,那都是命。


