专栏首页数据和云innodb实例损坏情况下恢复数据及相关工具的开发

innodb实例损坏情况下恢复数据及相关工具的开发

作者介绍:谢浩,现任职于云和恩墨(北京)信息技术有限公司,具有多年oracle数据库企业级运维经验,擅长结合业务、硬件系统制定各种项目方案,具有丰富mysql相关的工作经验。

假设你在使用MySQL中的InnoDB驱动,由于遇到了驱动程序错误,内核错误,电源故障或某些罕见的MySQL错误,而在InnoDB ibdata1文件损坏,实例不能启动。你该怎么办呢?

案例描述

某门户mysql innodb数据库实例损坏,数据库服务无法启动,使用文件系统上的数据库frm及bid文件恢复数据库内的业务数据。

相关知识点

Mysql innodb数据库将实例的基础字典信息存储在data目录下的ibdata1文件以及mysql实例中,可以将其理解为oracle数据库的system表空间以及数据字典,如果损坏数据实例将无法启动。

Mysql innodb引擎打开innodb_file_per_table后,每个表都会单独存放在一个表空间中,包含了tablename.frm和tablename.ibd文件,其中.frm后缀的文件记录表的结构信息,.ibd后缀的文件记录表的数据。在mysql实例无法启动的情况下使用这两个文件可以恢复数据库内的业务数据。

恢复过程中需要获得每个数据表的字段个数和每个表空间文件的table id(5.5版本),其中字段个数记录在frm文件中。

1、分析frm文件格式获得表字段个数

分析mysql源代码中位于table.cc文件中的open_binary_frm函数获得frm文件中记录字段数的位置:

open_binary_frm函数中位于table.cc文件第766行调用了get_from_pos函数,该函数负责计算frm文件内字段信息集合的起始偏移量:

该函数中首先seek到file head+64,然后读取“(head+4的dword)+(head+8的dword)*4”的数据,最后pos=buf+length,这里之所以不直接读取,是因为读到的位置可能不是双数,因此要从第64字节读取后整个buffer进行小头转换再读取最后的目标pos。

对该段代码进行解释,pos的值就是frm文件从第64字节开始,跳过head+4的dword内记录的字节数后读取(head+8的dword)*4个字节内的值。

举例说明:

第4、5字节为03 00,小头转换后为0003,第8、9字节为01 00,转换后为00 01。按上述算法,从第64字节开始读取3+1*4=7个字节,读取后进行小头转换为“2F 2F 00 00 00 20 00”,最后截取第3到结束为“00 00 20 00”等于10进制的8192,这就是frm文件中字段信息的保存起始偏移量。

再次观察open_binary_frm函数,我们需要的表字段数实际上是记录在字段信息的保存起始偏移量+258位置:

在本例中为8192+258=8450=0x2102的位置

04 00小头转换后为0004,表示该表有4个字段。

至此字段数量信息读取完成。

2、获得表对应的space_id

space_id 可以从ibd文件的第38~39字节、42~43字节两处处获得:

两处完全一样,读取其中一个即可。

手工恢复流程

1、模拟数据库字典信息损坏

将数据库data目录下ibdata文件改名为ibdata.1,此时启动数据库服务失败,err日志中出现以下信息:

2、在辅助实例生成数据表ddl语句

在目标库建立与原库名称相同字段数量相同的表(字段名任意),将原库frm文件复制到辅助实例,并设置innodb_force_recovery==6

3、在目标实例创建空表并分离数据

执行上述create table命令,对齐space_id,并执行表空间分离

4、使用原frm、ibd文件覆盖目标库同名文件

停止目标实例服务,将需要恢复的原数据库内的frm、ibd文件覆盖目标实例的同名文件,并import表空间:

恢复流程整理及相关工具开发

恢复过程中重要点如下:

1、批量快速获得表的字段数

生产系统包含大量数据表,人工逐个分析frm文件速度慢,需要开发工具批量自动获取。

2、批量获得space_id并生成对齐语句

Space_id的对齐是指在目标库某个表在全实例被创建的顺位必须相同(5.5版本,5.6及以上版本不需要),比如某个表在原库的space_id=100,在目标库上必须先建立99个空表,再建立这个表就能使该表的space_id相同。核心逻辑如下:

3、原地恢复

生产系统数据表数量多、体积大,全部复制到目标实例data目录下时间太长,因此需要将目标实例的data目录指向原实例,同时需要批量将原实例data目录下的所有文件改名。部分代码如下:

流程梳理

1、建立辅助实例、目标实例(人工)

2、批量获得原库表字段个数、space_id(工具)

3、辅助实例批量生成create table语句并自动生成space_id对齐(建空表)语句(工具)

4、目标库文件改名、目标库使用生成的createtable语句建立空表(工具)

5、目标库覆盖(工具)

本文分享自微信公众号 - 数据和云(OraNews),作者:谢浩

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2018-02-01

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Oracle 20c 新特性:自动的区域图 - Automatic Zone Maps

    导读:Zone Maps 是一个独立的访问结构,可以为表独立建立。在表和索引扫描期间,区块图可以根据表列上的谓词来修剪表的磁盘块和分区表的潜在完整分区。区块映射...

    数据和云
  • DB2单表排序查询报错分析及解决办法

    墨墨导读:客户DB2环境对单表的排序查询报错SQL1585N,本文模拟此报错并进行说明。

    数据和云
  • 没想到你是这样的Nginx!

    墨墨导读:Nginx是一个HTTP和反向代理服务,一个邮件代理服务,一个通用的TCP/UDP代理服务。Nginx可以提供HTTP、反向代理服务,邮件代理服务,通...

    数据和云
  • Java8:使用Lambda表达式增强版Comparator排序

    学习路上的自我记录-------路好长,就问你慌不慌,大声港,不慌。----jstarseven。

    大道七哥
  • 【STM32H7的DSP教程】第21章 DSP矩阵运算-加法,减法和逆矩阵

    完整版教程下载地址:http://www.armbbs.cn/forum.php?mod=viewthread&tid=94547

    armfly
  • 关于如何做一个“优秀网站”的清单——规范篇

    用户1687375
  • 从零开始搭建Nginx和Tomcat的web集群环境

    一直以来对于web服务器对tomcat还是很熟悉了,但是很对于nginx还是有些陌生,一看到nginx的配置就让人有一种莫名的排斥,这就是对于陌生的恐惧,我们今...

    企鹅号小编
  • docker网络之bridge

    https://blog.csdn.net/u014027051/article/details/53908878/

    charlieroro
  • MySql学习笔记(五)- 使用ShowProfile分析Sql

    上期文档中我们让mysql开启慢查询日志,收集查询时间比较长的sql,进而通过explain指令查询sql的执行过程,explain能够查看sql是那种数据查询...

    写一点笔记
  • 基于ThinkPHP5和Bootstrap的极速后台开发框架

    FastAdmin是一款基于ThinkPHP5+Bootstrap的极速后台开发框架。

    程序源代码

扫码关注云+社区

领取腾讯云代金券