假设你在使用MySQL中的InnoDB驱动,由于遇到了驱动程序错误,内核错误,电源故障或某些罕见的MySQL错误,而在InnoDB ibdata1文件损坏,实例不能启动。你该怎么办呢?
某门户mysql innodb数据库实例损坏,数据库服务无法启动,使用文件系统上的数据库frm及bid文件恢复数据库内的业务数据。
恢复过程中需要获得每个数据表的字段个数和每个表空间文件的table id(5.5版本),其中字段个数记录在frm文件中。
分析mysql源代码中位于table.cc文件中的open_binary_frm函数获得frm文件中记录字段数的位置:
open_binary_frm函数中位于table.cc文件第766行调用了get_from_pos函数,该函数负责计算frm文件内字段信息集合的起始偏移量:
对该段代码进行解释,pos的值就是frm文件从第64字节开始,跳过head+4的dword内记录的字节数后读取(head+8的dword)*4个字节内的值。
再次观察open_binary_frm函数,我们需要的表字段数实际上是记录在字段信息的保存起始偏移量+258位置:
space_id 可以从ibd文件的第38~39字节、42~43字节两处处获得:
将数据库data目录下ibdata文件改名为ibdata.1,此时启动数据库服务失败,err日志中出现以下信息:
在目标库建立与原库名称相同字段数量相同的表(字段名任意),将原库frm文件复制到辅助实例,并设置innodb_force_recovery==6
执行上述create table命令,对齐space_id,并执行表空间分离
停止目标实例服务,将需要恢复的原数据库内的frm、ibd文件覆盖目标实例的同名文件,并import表空间:
生产系统包含大量数据表,人工逐个分析frm文件速度慢,需要开发工具批量自动获取。
生产系统数据表数量多、体积大,全部复制到目标实例data目录下时间太长,因此需要将目标实例的data目录指向原实例,同时需要批量将原实例data目录下的所有文件改名。部分代码如下:
3、辅助实例批量生成create table语句并自动生成space_id对齐(建空表)语句(工具)
4、目标库文件改名、目标库使用生成的createtable语句建立空表(工具)
数据和云