26
MySQL 源源源源 —— InnoDB 源源源源源源 源源源 Alibaba DBA Team

MySQL源码分析.03.InnoDB 物理文件格式与数据恢复

Embed Size (px)

Citation preview

Page 1: MySQL源码分析.03.InnoDB 物理文件格式与数据恢复

MySQL 源码分析—— InnoDB 物理文件格式

彭立勋

Alibaba DBA Team

Page 2: MySQL源码分析.03.InnoDB 物理文件格式与数据恢复

Topics

• InnoDB 文件组织• InnoDB 表空间格式• InnoDB 页格式• InnoDB 行格式• InnoDB 数据文件恢复数据

Page 3: MySQL源码分析.03.InnoDB 物理文件格式与数据恢复

InnoDB 数据库文件组织

Page 4: MySQL源码分析.03.InnoDB 物理文件格式与数据恢复

InnoDB 系统表空间

• 内部数据字典• 回滚段• 插入缓冲• Double Write Buffer

• MySQL Replication Info

Page 5: MySQL源码分析.03.InnoDB 物理文件格式与数据恢复

InnoDB 表空间 (1)

• 一个表空间包含多个文件或者裸设备分区• 一个文件 (ibd)/ 分区包含一组分区 (segmen

t)

• 一个分区包含一组定长的页 (page)

• 未压缩的页大小总是 16KB(Percona 可修改 ) ,压缩页可以选择 1~16KB 。数据和索引不区分。

Page 6: MySQL源码分析.03.InnoDB 物理文件格式与数据恢复

InnoDB 表空间 (2)

Page 7: MySQL源码分析.03.InnoDB 物理文件格式与数据恢复

InnoDB 页格式 (1)

• 一个页包含:页头 (Page Header) ,页尾(Page Trailer) ,页体 (Page Body ,包含页内容 )

Page 8: MySQL源码分析.03.InnoDB 物理文件格式与数据恢复

InnoDB 页格式 (2)

Page 9: MySQL源码分析.03.InnoDB 物理文件格式与数据恢复

InnoDB 页类型 (1)

Page 10: MySQL源码分析.03.InnoDB 物理文件格式与数据恢复

InnoDB 页类型 (2)

• 数据页( B-Tree Node )• 回滚日志页( Undo Log Page )• 系统页( System Page )• 事物数据页( Transaction System Page )• 插入缓冲位图页( Insert Buffer Bitmap )• 插入缓冲空闲列表( Insert Buffer Free List )• 未压缩的二进制大对象页( Uncompressed BLO

B Page )• 压缩的二进制大对象页( Compressed BLOB Pa

ge )。

Page 11: MySQL源码分析.03.InnoDB 物理文件格式与数据恢复

InnoDB 非压缩数据页

• File Header :用来记录也的一些头信息。( 38 字节)

• Page Header :用来记录数据页的状态信息。( 56 字节)

• Page Directory :存放记录的页相对位置。

• Page Trailer :为了保证页完整的写入磁盘而设置。

File Header

Page Header

Infimum Record

User Records

Free Space

Supremum Record

Page Directory

Page Trailer

Page 12: MySQL源码分析.03.InnoDB 物理文件格式与数据恢复

InnoDB 压缩页

• InnoDB 在每个页设置了 Modification Log 记录变更

• 小记录的增改写到这个日志。• 删除不需要解压缩• 当页需要压缩适应页大小,这个

日志也负责提供此信息• 当日志空间用完, InnoDB 解压

页,应用变更后重新压缩。

Page 13: MySQL源码分析.03.InnoDB 物理文件格式与数据恢复

File Header(Fil0fil.h)

名称 大小 (B) 描述

FIL_PAGE_SPACE_OR_CHECKSUM 4

当 MySQL < 4.0.14 时表示该页属于哪个表空间,因为共享表空间中放了属于不同表空间的页。之后的 MyS

QL 用此值记录新的页 Checksum 值。FIL_PAGE_OFFSET 4 表空间中页的偏移量

FIL_PAGE_PREV/NEXT 4 当前页的上一个及下一个页 (B+ Tree)

FIL_PAGE_LSN 8 该页最后被修改的日志序列位置 LSN

FIL_PAGE_TYPE 2 页的类型FIL_PAGE_FILE_FLUSH

_LSN 8 该值仅在数据文件中的一个页中定义,代表文件至少被更新到了该 LSN 值

FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID 4 从 MySQL 4.1 开始,该值表示页属于哪个表空间

Page 14: MySQL源码分析.03.InnoDB 物理文件格式与数据恢复

Page Header(Page0page.h)

名称 大小 (B) 描述PAGE_N_DIR_SLOTS 2 在 Page Directory 中的 Slot 数。

PAGE_HEAP_TOP 2 堆中第一个记录的指针PAGE_N_HEAP 2 堆中的记录数

PAGE_FREE 2 指向空闲列表首指针PAGE_GARBAGE 2 已删除记录的字节数,即 deleted flag 为 1 的记录大小

PAGE_LAST_INSERT 2 最后插入记录的位置,如果被 DELETE 则此记录为 NULL

PAGE_DIRECTION 2 最后插入的方向, PAGE_LEFT(0x01) 等PAGE_N_RECS 2 该页中的记录数

PAGE_MAX_TRX_ID 8 修改当前页的最大事务 ID ,仅在非主键索引定义PAGE_LEVEL 2 当前页在索引树中的位置, 0x00 代表叶节点

PAGE_INDEX_ID 8 当前页属于哪个索引 ID

PAGE_BTR_SEG_LEAF 10 B+ 树叶节点中文件段的首指针位置。仅在 Root 页定义

PAGE_BTR_SEG_TOP 10 B+ 树非叶节点中文件段的首指针位置。仅在 Root 页定义

Page 15: MySQL源码分析.03.InnoDB 物理文件格式与数据恢复

Page Directory

• Slots :页目录中的记录指针成为槽,最少属于 4 条记录最多属于 8 条记录。

• Slots 中按照键顺序存放,所以可以用二分查找迅速找到记录的指针。

• Slots 是稀疏目录,只能找到粗略结果,不能准确定义到一条记录,需要通过 next_record来继续查找。

Page 16: MySQL源码分析.03.InnoDB 物理文件格式与数据恢复

Page Trailer

• 只有一个 FIL_AGE_END_LSN 部分,占 8字节。

• 前 4 字节表示该页 Checksum 值,后 4 字节和 File Header 的 FIL_PAGE_LSN 相同。通过这两个值和 File Header 的 FIL_PAGE_SPACE_OR_CHKSUM 及 FIL_PAGE_LSN 比较看是否一致来保证页完整性。

Page 17: MySQL源码分析.03.InnoDB 物理文件格式与数据恢复

InnoDB 行结构

Page 18: MySQL源码分析.03.InnoDB 物理文件格式与数据恢复

InnoDB Compact 行格式

变长字段长度列表 NULL标志位记录头信息

(5 Byte)TRX_ID(6 Byte)

ROLL_PTR(7 Byte)

……

名称 大小 (bit) 描述前两个 1 未知

deleted_flag 1 该行是否删除min_rec_flag 1 如果改行记录是预先被定义为最小的记录则为 1

n_owned 4 该行拥有的列数heap_no 13 索引堆中该条记录的排序记录

record_type 3 000= 普通 001=B+ 树节点指针 010=Infimum 011=Supermum 1XX= 保留

next_recorder 16 页中下一条记录的相对位置

Page 19: MySQL源码分析.03.InnoDB 物理文件格式与数据恢复

InnoDB 主键索引

• 数据存在聚集索引的叶子节点

• 数据按主键顺序组织,或者定义了非空唯一键。否则内部添加一个 6 字节的 ROW_ID 。

Page 20: MySQL源码分析.03.InnoDB 物理文件格式与数据恢复

InnoDB 主键索引

• 非主键索引在叶子节点记录数据,通过主键值指向主键索引,通过主键索引取回数据。

Page 21: MySQL源码分析.03.InnoDB 物理文件格式与数据恢复

InnoDB 日志

Page 22: MySQL源码分析.03.InnoDB 物理文件格式与数据恢复

InnoDB 重做日志

Page 23: MySQL源码分析.03.InnoDB 物理文件格式与数据恢复

InnoDB 物理文件恢复数据(1)

• 通过 page_parser 将页按结构解出(红色为 INDEX ID )

• #./page_parser -5 -f /data/mysqldata/mydata/plx/a.ibd

• Opening file: /data/mysqldata/mydata/plx/a.ibd• Read data from fn=3...• ……• Read page #3.. saving it to pages-1301329232/0-751/3-00000003.p

age• Read page #0.. saving it to pages-1301329232/0-0/4-00000000.pag

e• Read page #0.. saving it to pages-1301329232/0-0/5-00000000.pag

e

Page 24: MySQL源码分析.03.InnoDB 物理文件格式与数据恢复

InnoDB 物理文件恢复数据(2)

• CREATE TABLE innodb_table_monitor (id int) ENGINE=InnoDB; 打开 Monitor 查看 INDEX ID 。

• 例子中, INDEX ID 为 0-751 ,则解出的页在 0-751 目录。

• TABLE: name plx/a, id 0 246, columns 5, indexes 1, appr.rows 5• COLUMNS: id: DATA_INT DATA_UNSIGNED DATA_BINARY_TY

PE DATA_NOT_NULL len 4; info: DATA_BLOB len 10; DB_ROW_ID: DATA_SYS prtype 256 len 6; DB_TRX_ID: DATA_SYS prtype 257 len 6; DB_ROLL_PTR: DATA_SYS prtype 258 len 7;

• INDEX: name PRIMARY, id 0 751, fields 1/4, uniq 1, type 3• root page 3, appr.key vals 5, leaf pages 1, size pages 1• FIELDS: id DB_TRX_ID DB_ROLL_PTR info

Page 25: MySQL源码分析.03.InnoDB 物理文件格式与数据恢复

InnoDB 物理文件恢复数据(3)

• 如果还能打开数据则登陆数据库导出表结构定义为内部格式。根据需要修改表结构定义以除去不合理的数据。

• ./create_defs.pl --host=localhost --user=root --db=plx --table=a > include/table_defs.h

Page 26: MySQL源码分析.03.InnoDB 物理文件格式与数据恢复

InnoDB 物理文件恢复数据(4)

• 根据表结构重新 make然后导出数据。

• #./constraints_parser -5 -f pages-1301316207/0-751/3-00000003.page

• a 1 "a"• a 2 "b"• a 3 "c"• a 4 "d"• a 5 "e"• a 6 "f"• ./constraints_parser -5 -D -f pages-1301316207/0-751/3-00000003.

page ( 只导出被删除的 )• a 1 "a"