如果文件系统损坏或意外删除了数据库文件,只要磁盘空间没有被覆盖,其实数据都还在磁盘的扇区中,还是可以恢复出来的,有些通用的文件恢复工具好象也可以恢复文件 ,但这里要研究的是在通用文件 恢复工具失效的时候。

innodb文件是按页保存的,这为打捞工作提供了非常有利的条件,页面具有一些特征,我们可以根据页面特征来把数据页从磁盘中提取出来,也就是数据打捞。

决大多数内容都是抄自网络,但也有错误,2016.0505 20:49

Innodb表空间的概念:
表空间,数据文件的集合,在innodb就是idb文件集合.
一个表空间可以有多个idb文件 组成;
innodb会对数据文件每16k进行编号(从0开始),作为该页的页号,并且相邻文件的编号是也是连贯的;
Innodb使用表空间id来区分不同的表空间,共享表空间的id总是为0,其他独立表空间的id依次递增。那么,某个页面的唯一标识就是<strong>(space_id, page_no);</strong>
(ps:昨天我扫描我电脑上的ibdata1)

首先,我们需要知道innodb文件页面结构和结构中每个部分的特征;
页面整体结构,图片来源网络(http://www.cnblogs.com/vinchen/archive/2012/09/10/2679478.html)

<span style="font-size: x-large;"><img class="alignnone size-medium wp-image-159" src="http://www.veryjuly.com/blog/wp-content/uploads/2016/05/2012091022353013-300x220.jpg" alt="2012091022353013" width="300" height="220" /></span>

1. 页头(Page Header):记录页面的控制信息,共占150字节,包括页的左右兄弟页面指针、页面空间使用情况等,

(上面的150可能是错误的,应该是38+36+20=94,这个位置基本就到最小虚记录了)

2. 最小虚记录、最大虚记录:两个固定位置存储的虚记录,本身并不存储数据。最小虚记录比任何记录都小,而最大虚记录比任何记录都大。

3. 记录堆(record heap):指上图的橙黄色部分。表示页面已分配的记录空间,也是索引数据的真正存储区域。记录堆分为两种,即有效记录和已删除记录。有效记录就是索引正常使用的记录,而已删除记录表示索引已经删除,不在使用的记录,如上图的深蓝色部分。随着记录的更新和删除越来越频繁,记录堆中已删除记录将会越多,即会出现越来越多的空洞(碎片)。这些已删除记录连接起来,就会成为页面的自由空间链表。

4. 未分配空间:指页面未使用的存储空间,随着页面不断使用,未分配空间将会越来越小。当新插入一条记录时,首先尝试从自由空间链表中获得合适的存储位置(空间足够),如果没有满足的,就会在未分配空间中申请。

5. slot区:slot是一些页面有效记录的指针,每个slot占两个字节,存储了记录相对页面首地址的偏移。如果页面有n条有效记录,那么slot的数量就在n/8+2~n/4+2之间。下一节详细介绍slot区,它是记录页面有序和二分查找的关键
6. 页尾(Page Tailer):页面最后部分,占8个字节,主要存储页面的校验信息。

页面中的页头,最大/最小虚记录以及页尾都是页面中有固定的存储位置。
<div>特征主要在Page Header中,但文件 数据部分也有些特征,文件尾也可能是一个特征;</div>
Page Header结构与特征:(分成通用头和不同页类型的头)
*通用页头:表示所有页面都使用的页头,占38个字节;
*数据页头:接下来的112个字节是数据页头,表示数据页的头信息,(根据通用头中不同的页类型这里是不同的头,但我们打捞数据时更关心数据页头,因为数据都保存中数据页中,也就是页类型为FIL_PAGE_INDEX)
数据页页头的总大小为38+112=150字节;

通用页头:(源码中有关通用头的定义在文件 :file0fil.h中)

通用页头共占38个字节,依次为。
*页面checksum值(4字节):页面内容的校验值,用于校验页面内容的合法性和可靠性,
(如果能找出算法,数据打捞时判断页面将是一个很有效的字段)

•页号(4字节):页面在表空间的页号
•左兄弟页面的页号(4字节):上一篇第一节介绍了B+树的基础内容,提到相同层次页面是通过一个双向链表连接起来的。而左兄弟页号就是该页在链表中的左兄弟页号。当然,左右兄弟页面都必须属于同一表空间。
•右兄弟页面的页号(4字节):同上,右兄弟页号。

*页面LSN(8字节):页面最后一次修改的LSN值,用于页面刷盘和恢复。LSN是一个递增的日志序列号。
*页面类型(2字节):innodb有若干种页面类型,通过这个可以区分,数据页面页面类型都为FIL_PAGE_INDEX(17855)。
(17855很有意思呀,简直就是为数据打捞准备的,数据都是保存在这人h类型的页面中的,我们要的就是这个类型的页面,理论只靠这个标志就可以让垃圾块出现的几率小到1/64K,按簇大小4K算,每256G的磁盘才会出现一个垃圾块)

•文件刷盘LSN(8字节):只有共享表空间各文件首页使用,记录服务器正常结束的LSN值,一般只用于检查和校验
如果是这样,也就是说正常的数据页不用吗,那这样就又是一人h标识)
•表空间ID(4字节):表空间ID;(如果表空间从0开始的话,那么正常的数据库表空间ID都不会在y大,这也许也是个判断依据。)
2.2 数据页头
数据页头共占112个字节,成员比较多,也相对复杂些,由低字节到高字节,包括一下成员:

PAGE_N_DIR_SLOTS(2字节):指slot区的slot的个数,每个slot两个字节。
PAGE_HEAP_TOP(2字节):堆顶指针,未分配空间的首地址
(如果是相对页的位置,那么应该在页头之后)

PAGE_N_HEAP(2字节):记录堆内记录数,包括已删除记录和最大最小虚记录。因此,初始化为2。第15 bit为1表示row_format=compact

PAGE_FREE(2字节):第一个已删除记录偏移。所有已删除记录连接在一起成为自由空间链表。
(又是偏移,可以判断一下了)

PAGE_GARBAGE(2字节):已删除记录占用的总字节数,即记录堆内已删除的总空间大小。
PAGE_LAST_INSERT(2字节):最后一次插入记录的偏移
PAGE_DIRECTION(2字节):页面最后一次的插入方向,如果本次插入比上次插入的值大就是PAGE_RIGHT,反之就是PAGE_LEFT;

PAGE_N_DIRECTION(2字节):相同插入方向的连续插入次数
PAGE_N_RECS(2字节):页面有效记录数
PAGE_MAX_TRX_ID(8字节):最后一次改变页面的事务ID,仅在二级索引中有效,用于二级索引记录MVCC多版本可见性判断。

PAGE_LEVEL(2字节):页面在索引中的层次,叶子节点层次为0。
PAGE_INDEX_ID(8字节):页面所属索引的ID。
(这个在数据恢复中很重要,)
PAGE_BTR_SEG_LEAF(10字节):叶子节点段头inode信息,仅在B+树的根页有效
PAGE_BTR_SEG_TOP(10字节):内节点段头inode信息,仅在B+树的根页有效
数据页头的成员较多,PAGE_N_DIR_SLOTS、PAGE_N_HEAP、PAGE_N_RECS比较简单,主要

4. 页尾
页尾是页面的最后8个字节,包括两部分,主要用于页面内容的校验,其中包括:

OLD_CHKSUM:4字节,页尾的checksum值,与通用页头的页面checksum值使用不同的算法。
LSN_LOWER_4BYTES:4字节,记录通用页头中页面LSN的低四字节。
通过页头的页面checksum值、页面LSN和页尾的OLD_CHKSUM、LSN_LOWER_4BYTES可以判断一个页面是否corrupted,判断算法是(详见函数buf_page_is_corrupted):

1. 判断LSN_LOWER_4BYTES是否等于页面LSN的低四字节,若不相等,返回TRUE。

用于页面计数,每次页面插入、更新或删除记录,都有可能影响这些值。而其他页头可以通过一些具体操作介绍其关键作用。

mysql innodb 数据打捞(一)innodb 页面结构特征的更多相关文章

  1. mysql innodb 数据打捞(二)innodb 页面打捞编程

    有了页面的结构和特征,需要编程实现数据库页面的打捞工作: 为了方便windows and linux 的通用,计划做成C语言的控制台应用,并且尽量只用ansi c;关于多线程,计划做成多线程的程序,最 ...

  2. mysql innodb 数据打捞(三)innodb 簇不连接页的扫描提取(计划)

    操作系统簇大小一般是4K,而innoDB的页大小一般是16K,那么就有可能16K的页没有存储在连续的簇中,这样扫描软件就不会扫描出来这样的页面.为了解决这个问题,决定给软件增加半页扫描功能. 在第一次 ...

  3. mysql innodb 数据打捞(四)innodb 簇不连续页扫描提取(试验)

    一,用winhex把正常页有意做成不连续的两部分,把后8K向后移动4K,中间隔开4K,启动第一次扫描; 扫描结果是,没有提取到有效页面,但在输出目录生成两个文件:upper.pages和upper.l ...

  4. InnoDB数据页结构

    前言 ​ 关于数据库我们知道是通过内存对磁盘进行操作的,也知道数据会落实到磁盘上,但是数据在磁盘上的存储结构可能大家还不是很清楚. ​ MySQL服务器上负责对表中的数据的读取和写入的工作的部分是存储 ...

  5. MySQL · 引擎特性 · InnoDB 数据页解析

    前言 之前介绍的月报中,详细介绍了InnoDB Buffer Pool的实现细节,Buffer Pool主要就是用来存储数据页的,是数据页在内存中的动态存储方式,而本文介绍一下数据页在磁盘上的静态存储 ...

  6. Mysql+innodb数据存储逻辑

    Mysql+innodb数据存储逻辑. 表空间由段,区,页组成 ibdata1:共享表空间.即所有的数据都存放在这个表空间内.如果用户启用了innodb_file_per_table,则每张表内的数据 ...

  7. 细看InnoDB数据落盘 图解 MYSQL 专家hatemysql

    http://hatemysql.com/?p=503 1.  概述 前面很多大侠都分享过MySQL的InnoDB存储引擎将数据刷新的各种情况.我们这篇文章从InnoDB往下,看看数据从InnoDB的 ...

  8. MySQL之InnoDB数据页结构(转自掘金小册 MySQL是怎样运行的,版权归作者所有!)

    InnoDB为了不同的目的而设计了不同类型的页,我们把用于存放记录的页叫做数据页. 一个数据页可以被大致划分为7个部分,分别是 File Header,表示页的一些通用信息,占固定的38字节. Pag ...

  9. __细看InnoDB数据落盘 图解 MYSQL

    http://hatemysql.com/?p=503 1.  概述 前面很多大侠都分享过MySQL的InnoDB存储引擎将数据刷新的各种情况.我们这篇文章从InnoDB往下,看看数据从InnoDB的 ...

随机推荐

  1. Hibernate映射文件简单配置

    <?xml version="1.0" ?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibe ...

  2. ECSHOP模板文件说明

    最新ECSHOP 2.7.3完整的一套ECSHOP模板有一下构造 • 35个 .dwt文件(模板框架文件.可调用lbi库文件的主体文件) • 57个 .lbi文件(模板库文件,可通过后台库项目管理直接 ...

  3. 【转】/etc/grub.conf文件详解

    转自:http://leejia.blog.51cto.com/4356849/788902 grub.conf是grub的主配置文件,通过这个配置文件,grub才能找到kernel,系统才能正常启动 ...

  4. POJ 2778 DNA Sequence (AC自己主动机 + dp)

    DNA Sequence 题意:DNA的序列由ACTG四个字母组成,如今给定m个不可行的序列.问随机构成的长度为n的序列中.有多少种序列是可行的(仅仅要包括一个不可行序列便不可行).个数非常大.对10 ...

  5. Centos部署nagios+apache实现服务器监控

    1.Nagios介绍 nagios是 一款功能强大的网络监视工具,它可以有效的监控windows.linux.unix主机状态以及路由器交换机的网络设置,打印机工作状态等,并将状态出 现异常的服务及时 ...

  6. [GIF] Parenting in GIF Loop Coder

    In this lesson, we look at how you can build up complex animations by assigning one shape as the par ...

  7. ABAP程序执行效率和优化 ABAP Performance Examples

    一.             SQL Interface1.         Select ... Where vs. Select + Check用Select … Where语句效率比Select ...

  8. 使用 Docker 搭建 Java Web 运行环境

    黄勇的博客 Docker 是 2014 年最为火爆的技术之一,几乎所有的程序员都听说过它.Docker 是一种“轻量级”容器技术,它几乎动摇了传统虚拟化技术的地位,现在国内外已经有越来越多的公司开始逐 ...

  9. C#数据采集类

    using System; using System.Data; using System.Configuration; using System.Web; using System.Web.Secu ...

  10. mysql与java的之间的连接

    package cn.hncu; //注意,以下都是sun公司的接口(类)---这样以后换成Oracle等其它数据库,代码不用动import java.sql.Connection;import ja ...