mysql innodb 数据打捞(一)innodb 页面结构特征
如果文件系统损坏或意外删除了数据库文件,只要磁盘空间没有被覆盖,其实数据都还在磁盘的扇区中,还是可以恢复出来的,有些通用的文件恢复工具好象也可以恢复文件 ,但这里要研究的是在通用文件 恢复工具失效的时候。
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 页面结构特征的更多相关文章
- mysql innodb 数据打捞(二)innodb 页面打捞编程
有了页面的结构和特征,需要编程实现数据库页面的打捞工作: 为了方便windows and linux 的通用,计划做成C语言的控制台应用,并且尽量只用ansi c;关于多线程,计划做成多线程的程序,最 ...
- mysql innodb 数据打捞(三)innodb 簇不连接页的扫描提取(计划)
操作系统簇大小一般是4K,而innoDB的页大小一般是16K,那么就有可能16K的页没有存储在连续的簇中,这样扫描软件就不会扫描出来这样的页面.为了解决这个问题,决定给软件增加半页扫描功能. 在第一次 ...
- mysql innodb 数据打捞(四)innodb 簇不连续页扫描提取(试验)
一,用winhex把正常页有意做成不连续的两部分,把后8K向后移动4K,中间隔开4K,启动第一次扫描; 扫描结果是,没有提取到有效页面,但在输出目录生成两个文件:upper.pages和upper.l ...
- InnoDB数据页结构
前言 关于数据库我们知道是通过内存对磁盘进行操作的,也知道数据会落实到磁盘上,但是数据在磁盘上的存储结构可能大家还不是很清楚. MySQL服务器上负责对表中的数据的读取和写入的工作的部分是存储 ...
- MySQL · 引擎特性 · InnoDB 数据页解析
前言 之前介绍的月报中,详细介绍了InnoDB Buffer Pool的实现细节,Buffer Pool主要就是用来存储数据页的,是数据页在内存中的动态存储方式,而本文介绍一下数据页在磁盘上的静态存储 ...
- Mysql+innodb数据存储逻辑
Mysql+innodb数据存储逻辑. 表空间由段,区,页组成 ibdata1:共享表空间.即所有的数据都存放在这个表空间内.如果用户启用了innodb_file_per_table,则每张表内的数据 ...
- 细看InnoDB数据落盘 图解 MYSQL 专家hatemysql
http://hatemysql.com/?p=503 1. 概述 前面很多大侠都分享过MySQL的InnoDB存储引擎将数据刷新的各种情况.我们这篇文章从InnoDB往下,看看数据从InnoDB的 ...
- MySQL之InnoDB数据页结构(转自掘金小册 MySQL是怎样运行的,版权归作者所有!)
InnoDB为了不同的目的而设计了不同类型的页,我们把用于存放记录的页叫做数据页. 一个数据页可以被大致划分为7个部分,分别是 File Header,表示页的一些通用信息,占固定的38字节. Pag ...
- __细看InnoDB数据落盘 图解 MYSQL
http://hatemysql.com/?p=503 1. 概述 前面很多大侠都分享过MySQL的InnoDB存储引擎将数据刷新的各种情况.我们这篇文章从InnoDB往下,看看数据从InnoDB的 ...
随机推荐
- mysql之存储引擎
1.存储引擎概念 打比方说:一部电影有mp4,wmv,avi,flv...等格式.同样的一部电影在硬盘上有不同的存储格式,所占的空间与清晰程度也各不一样. 那么我们表里的数据存储在硬盘上,是如何存储的 ...
- svn 如何解决冲突
项目中,往往不止你一人开发,多人开发,难免会有代码的冲突.彼此间谁也不能保证不会修改同个文件.如果修改了同个方法的内容.这时提交到svn是会提示代码冲突的. 当然,冲突是可控的,但不能避免.每次写代码 ...
- iOS开发-在表单元中添加子视图
#import <UIKit/UIKit.h> @interface NameAndColorCellTableViewCell : UITableViewCell @property(c ...
- cocos2d-x Menu、MenuItem
转自:http://codingnow.cn/cocos2d-x/832.html 学习cocos2d-x中的菜单主要需要了解:菜单(CCMenu)和菜单项(CCMenuItem)以及CCMenuIt ...
- 08重编终极版《东邪西毒:终极版》DVD粤语中字
1.东邪西毒].Ashes.of.Time.1994.384p.DVDRip.x264.ac3-DTMM.mkv 这个版本最清晰 ,可惜删减了,只有87分钟,粤语,1.4G. 2.东邪西毒(初始版). ...
- SCOM MP中的PowerShell脚本
该脚本可在MP中运行 #param ($file,$threshold) #此处可定义file 和 threshold 参数,该参数可以从脚本外部接收 $threshold = 10 $file = ...
- Android端如何获取手机当前的网络状态,比如wifi还是3G, 还是2G, 电信还是联通,还是移动
不多说了,直接看代码, NB人会懂的! package com.example.vdisktest; import android.app.Activity; import android.conte ...
- NET中間語言(IL) 图解
转载地址是:http://msdn.microsoft.com/zh-tw/library/dd229210.aspx 想查看IL指令,请看中英文对照表: CN-http://www.cnblogs. ...
- RHEL6中ulimit的nproc限制
http://blog.csdn.net/kumu_linux/article/details/8301760 当前shell下更改用户可打开进程数 修改limits.conf配置文件生效 [root ...
- const形参和实参
当形参是const时,必须要注意关于顶层const的讨论.如前所述,顶层const的作用于对象本身: const int ci=42; //不能改变ci,const是顶层的 int i=ci: ...