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的 ...
随机推荐
- Hibernate映射文件简单配置
<?xml version="1.0" ?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibe ...
- ECSHOP模板文件说明
最新ECSHOP 2.7.3完整的一套ECSHOP模板有一下构造 • 35个 .dwt文件(模板框架文件.可调用lbi库文件的主体文件) • 57个 .lbi文件(模板库文件,可通过后台库项目管理直接 ...
- 【转】/etc/grub.conf文件详解
转自:http://leejia.blog.51cto.com/4356849/788902 grub.conf是grub的主配置文件,通过这个配置文件,grub才能找到kernel,系统才能正常启动 ...
- POJ 2778 DNA Sequence (AC自己主动机 + dp)
DNA Sequence 题意:DNA的序列由ACTG四个字母组成,如今给定m个不可行的序列.问随机构成的长度为n的序列中.有多少种序列是可行的(仅仅要包括一个不可行序列便不可行).个数非常大.对10 ...
- Centos部署nagios+apache实现服务器监控
1.Nagios介绍 nagios是 一款功能强大的网络监视工具,它可以有效的监控windows.linux.unix主机状态以及路由器交换机的网络设置,打印机工作状态等,并将状态出 现异常的服务及时 ...
- [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 ...
- ABAP程序执行效率和优化 ABAP Performance Examples
一. SQL Interface1. Select ... Where vs. Select + Check用Select … Where语句效率比Select ...
- 使用 Docker 搭建 Java Web 运行环境
黄勇的博客 Docker 是 2014 年最为火爆的技术之一,几乎所有的程序员都听说过它.Docker 是一种“轻量级”容器技术,它几乎动摇了传统虚拟化技术的地位,现在国内外已经有越来越多的公司开始逐 ...
- C#数据采集类
using System; using System.Data; using System.Configuration; using System.Web; using System.Web.Secu ...
- mysql与java的之间的连接
package cn.hncu; //注意,以下都是sun公司的接口(类)---这样以后换成Oracle等其它数据库,代码不用动import java.sql.Connection;import ja ...