Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

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

3,290 views

Published on

Published in: Technology
  • Sex in your area is here: ❤❤❤ http://bit.ly/2F7hN3u ❤❤❤
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • Dating for everyone is here: ❶❶❶ http://bit.ly/2F7hN3u ❶❶❶
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here

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

  1. 1. MySQL 源码分析 —— InnoDB 物理文件格式 彭立勋 Alibaba DBA Team
  2. 2. Topics <ul><li>InnoDB 文件组织 </li></ul><ul><li>InnoDB 表空间格式 </li></ul><ul><li>InnoDB 页格式 </li></ul><ul><li>InnoDB 行格式 </li></ul><ul><li>InnoDB 数据文件恢复数据 </li></ul>
  3. 3. InnoDB 数据库文件组织
  4. 4. InnoDB 系统表空间 <ul><li>内部数据字典 </li></ul><ul><li>回滚段 </li></ul><ul><li>插入缓冲 </li></ul><ul><li>Double Write Buffer </li></ul><ul><li>MySQL Replication Info </li></ul>
  5. 5. InnoDB 表空间 (1) <ul><li>一个表空间包含多个文件或者裸设备分区 </li></ul><ul><li>一个文件 (ibd)/ 分区包含一组分区 (segment) </li></ul><ul><li>一个分区包含一组定长的页 (page) </li></ul><ul><li>未压缩的页大小总是 16KB(Percona 可修改 ) ,压缩页可以选择 1~16KB 。数据和索引不区分。 </li></ul>
  6. 6. InnoDB 表空间 (2)
  7. 7. InnoDB 页格式 (1) <ul><li>一个页包含:页头 (Page Header) ,页尾 (Page Trailer) ,页体 (Page Body ,包含页内容 ) </li></ul>
  8. 8. InnoDB 页格式 (2)
  9. 9. InnoDB 页类型 (1)
  10. 10. InnoDB 页类型 (2) <ul><li>数据页( B-Tree Node ) </li></ul><ul><li>回滚日志页( Undo Log Page ) </li></ul><ul><li>系统页( System Page ) </li></ul><ul><li>事物数据页( Transaction System Page ) </li></ul><ul><li>插入缓冲位图页( Insert Buffer Bitmap ) </li></ul><ul><li>插入缓冲空闲列表( Insert Buffer Free List ) </li></ul><ul><li>未压缩的二进制大对象页( Uncompressed BLOB Page ) </li></ul><ul><li>压缩的二进制大对象页( Compressed BLOB Page )。 </li></ul>
  11. 11. InnoDB 非压缩数据页 <ul><li>File Header :用来记录也的一些头信息。( 38 字节) </li></ul><ul><li>Page Header :用来记录数据页的状态信息。( 56 字节) </li></ul><ul><li>Page Directory :存放记录的页相对位置。 </li></ul><ul><li>Page Trailer :为了保证页完整的写入磁盘而设置。 </li></ul>File Header User Records Supremum Record Free Space Infimum Record Page Header Page Trailer Page Directory
  12. 12. InnoDB 压缩页 <ul><li>InnoDB 在每个页设置了 Modification Log 记录变更 </li></ul><ul><li>小记录的增改写到这个日志。 </li></ul><ul><li>删除不需要解压缩 </li></ul><ul><li>当页需要压缩适应页大小,这个日志也负责提供此信息 </li></ul><ul><li>当日志空间用完, InnoDB 解压页,应用变更后重新压缩。 </li></ul>
  13. 13. File Header(Fil0fil.h) 名称 大小 (B) 描述 FIL_PAGE_SPACE_OR_CHECKSUM 4 当 MySQL < 4.0.14 时表示该页属于哪个表空间,因为共享表空间中放了属于不同表空间的页。之后的 MySQL 用此值记录新的页 Checksum 值。 FIL_PAGE_TYPE 2 页的类型 FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID 4 从 MySQL 4.1 开始,该值表示页属于哪个表空间 FIL_PAGE_FILE_FLUSH_LSN 8 该值仅在数据文件中的一个页中定义,代表文件至少被更新到了该 LSN 值 FIL_PAGE_LSN 8 该页最后被修改的日志序列位置 LSN FIL_PAGE_PREV/NEXT 4 当前页的上一个及下一个页 (B+ Tree) FIL_PAGE_OFFSET 4 表空间中页的偏移量
  14. 14. Page Header(Page0page.h) 名称 大小 (B) 描述 PAGE_N_DIR_SLOTS 2 在 Page Directory 中的 Slot 数。 PAGE_GARBAGE 2 已删除记录的字节数,即 deleted flag 为 1 的记录大小 PAGE_BTR_SEG_TOP 10 B+ 树非叶节点中文件段的首指针位置。仅在 Root 页定义 PAGE_LAST_INSERT 2 最后插入记录的位置,如果被 DELETE 则此记录为 NULL PAGE_FREE 2 指向空闲列表首指针 PAGE_N_HEAP 2 堆中的记录数 PAGE_HEAP_TOP 2 堆中第一个记录的指针 PAGE_DIRECTION 2 最后插入的方向, PAGE_LEFT(0x01) 等 PAGE_MAX_TRX_ID 8 修改当前页的最大事务 ID ,仅在非主键索引定义 PAGE_N_RECS 2 该页中的记录数 PAGE_INDEX_ID 8 当前页属于哪个索引 ID PAGE_LEVEL 2 当前页在索引树中的位置, 0x00 代表叶节点 PAGE_BTR_SEG_LEAF 10 B+ 树叶节点中文件段的首指针位置。仅在 Root 页定义
  15. 15. Page Directory <ul><li>Slots :页目录中的记录指针成为槽,最少属于 4 条记录最多属于 8 条记录。 </li></ul><ul><li>Slots 中按照键顺序存放,所以可以用二分查找迅速找到记录的指针。 </li></ul><ul><li>Slots 是稀疏目录,只能找到粗略结果,不能准确定义到一条记录,需要通过 next_record 来继续查找。 </li></ul>
  16. 16. Page Trailer <ul><li>只有一个 FIL_AGE_END_LSN 部分,占 8 字节。 </li></ul><ul><li>前 4 字节表示该页 Checksum 值,后 4 字节和 File Header 的 FIL_PAGE_LSN 相同。通过这两个值和 File Header 的 FIL_PAGE_SPACE_OR_CHKSUM 及 FIL_PAGE_LSN 比较看是否一致来保证页完整性。 </li></ul>
  17. 17. InnoDB 行结构
  18. 18. InnoDB Compact 行格式 变长字段长度列表 NULL 标志位 记录头信息 (5 Byte) TRX_ID (6 Byte) ROLL_PTR (7 Byte) …… 名称 大小 (bit) 描述 前两个 1 未知 min_rec_flag 1 如果改行记录是预先被定义为最小的记录则为 1 deleted_flag 1 该行是否删除 n_owned 4 该行拥有的列数 heap_no 13 索引堆中该条记录的排序记录 record_type 3 000= 普通 001=B+ 树节点指针 010=Infimum 011=Supermum 1XX= 保留 next_recorder 16 页中下一条记录的相对位置
  19. 19. InnoDB 主键索引 <ul><li>数据存在聚集索引的叶子节点 </li></ul><ul><li>数据按主键顺序组织,或者定义了非空唯一键。否则内部添加一个 6 字节的 ROW_ID 。 </li></ul>
  20. 20. InnoDB 主键索引 <ul><li>非主键索引在叶子节点记录数据,通过主键值指向主键索引,通过主键索引取回数据。 </li></ul>
  21. 21. InnoDB 日志
  22. 22. InnoDB 重做日志
  23. 23. InnoDB 物理文件恢复数据 (1) <ul><li>通过 page_parser 将页按结构解出(红色为 INDEX ID ) </li></ul><ul><li>#./page_parser -5 -f /data/mysqldata/mydata/plx/a.ibd </li></ul><ul><li>Opening file: /data/mysqldata/mydata/plx/a.ibd </li></ul><ul><li>Read data from fn=3... </li></ul><ul><li>…… </li></ul><ul><li>Read page #3.. saving it to pages-1301329232/ 0-751 /3-00000003.page </li></ul><ul><li>Read page #0.. saving it to pages-1301329232/ 0-0 /4-00000000.page </li></ul><ul><li>Read page #0.. saving it to pages-1301329232/ 0-0 /5-00000000.page </li></ul>
  24. 24. InnoDB 物理文件恢复数据 (2) <ul><li>CREATE TABLE innodb_table_monitor (id int) ENGINE=InnoDB; 打开 Monitor 查看 INDEX ID 。 </li></ul><ul><li>例子中, INDEX ID 为 0-751 ,则解出的页在 0-751 目录。 </li></ul><ul><li>TABLE: name plx/a, id 0 246, columns 5, indexes 1, appr.rows 5 </li></ul><ul><li>COLUMNS: id: DATA_INT DATA_UNSIGNED DATA_BINARY_TYPE 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; </li></ul><ul><li>INDEX: name PRIMARY, id 0 751 , fields 1/4, uniq 1, type 3 </li></ul><ul><li>root page 3, appr.key vals 5, leaf pages 1, size pages 1 </li></ul><ul><li>FIELDS: id DB_TRX_ID DB_ROLL_PTR info </li></ul>
  25. 25. InnoDB 物理文件恢复数据 (3) <ul><li>如果还能打开数据则登陆数据库导出表结构定义为内部格式。根据需要修改表结构定义以除去不合理的数据。 </li></ul><ul><li>./create_defs.pl --host=localhost --user=root --db=plx --table=a > include/table_defs.h </li></ul>
  26. 26. InnoDB 物理文件恢复数据 (4) <ul><li>根据表结构重新 make 然后导出数据。 </li></ul><ul><li>#./constraints_parser -5 -f pages-1301316207/0-751/3-00000003.page </li></ul><ul><li>a 1 &quot;a&quot; </li></ul><ul><li>a 2 &quot;b&quot; </li></ul><ul><li>a 3 &quot;c&quot; </li></ul><ul><li>a 4 &quot;d&quot; </li></ul><ul><li>a 5 &quot;e&quot; </li></ul><ul><li>a 6 &quot;f&quot; </li></ul><ul><li>./constraints_parser -5 -D -f pages-1301316207/0-751/3-00000003.page ( 只导出被删除的 ) </li></ul><ul><li>a 1 &quot;a&quot; </li></ul>

×