文章目录
一、InnoDB 数据页存储结构
innodb 存储引擎数据页结构如图所示:
InnoDB 数据页由 7 个部分组成:
- File Header :文件头
- Page Header:页头
- Infimun 和 Supremum Records
- User Records:用户记录,即行记录
- Free Space:空闲空间
- Page Directory:页目录
- File Trailer:文件结尾信息
1. File Header
File Header
用来记录页的一些头信息,共占用 38 个字节,具体记录了哪些信息如下表所示:
名称大小说明FIL_PAGE_SPACE_OR_CHKSUM4MySQL 版本 4. 0 之前该值为 0,版本 4.0 之后该值代表页的 checksum 值FIL_PAGE_OFFSET4表空间中页的偏移量,表示当前页在所有页中的偏移量,例如(10,1)表示查找表空间 ID 为 10 的第二个页FIL_PAGE_PREV4当前页的上一个页,B+ 树的叶子节点之间链接形成双向链表FIL_PAGE_NEXT4当前页的下一个页,B+ 树的叶子节点之间链接形成双向链表FIL_PAGE_LSN8代表当前页最后被修改的日志序列位置FIL_PAGE_TYPE2InnoDB 存储引擎页的类型FIL_PAGE_FILE_FLUSH_LSN8该值仅仅在 系统表空间 的一个页中定义,对于独立表空间该值为0,含义是文件至少被更新到了该 LSN 值FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID4MySQL 版本 4.1 之后,该值表示页属于哪个表空间
FIL_PAGE_TYPE
的取值和含义如下表所示:
/** File page types (values of FIL_PAGE_TYPE) @{ */#defineFIL_PAGE_INDEX17855/*!< B-tree node */#defineFIL_PAGE_RTREE17854/*!< B-tree node */#defineFIL_PAGE_UNDO_LOG2/*!< Undo log page */#defineFIL_PAGE_INODE3/*!< Index node */#defineFIL_PAGE_IBUF_FREE_LIST4/*!< Insert buffer free list *//* File page types introduced in MySQL/InnoDB 5.1.7 */#defineFIL_PAGE_TYPE_ALLOCATED0/*!< Freshly allocated page */#defineFIL_PAGE_IBUF_BITMAP5/*!< Insert buffer bitmap */#defineFIL_PAGE_TYPE_SYS6/*!< System page */#defineFIL_PAGE_TYPE_TRX_SYS7/*!< Transaction system data */#defineFIL_PAGE_TYPE_FSP_HDR8/*!< File space header */#defineFIL_PAGE_TYPE_XDES9/*!< Extent descriptor page */#defineFIL_PAGE_TYPE_BLOB10/*!< Uncompressed BLOB page */#defineFIL_PAGE_TYPE_ZBLOB11/*!< First compressed BLOB page */#defineFIL_PAGE_TYPE_ZBLOB212/*!< Subsequent compressed BLOB page */#defineFIL_PAGE_TYPE_UNKNOWN13/*!< In old tablespaces, garbage in FIL_PAGE_TYPE is replaced with this value when flushing pages. */#defineFIL_PAGE_COMPRESSED14/*!< Compressed page */#defineFIL_PAGE_ENCRYPTED15/*!< Encrypted page */#defineFIL_PAGE_COMPRESSED_AND_ENCRYPTED16/*!< Compressed and Encrypted page */#defineFIL_PAGE_ENCRYPTED_RTREE17/*!< Encrypted R-tree page */
常量名称十六进制含义FIL_PAGE_INDEX0x45BFB+ 数叶子节点(数据节点)FIL_PAGE_UNDO_LOG0x0002undo log 页FIL_PAGE_INODE0x0003索引节点FIL_PAGE_IBUF_FREE_LIST0x0004insert buffer 空闲列表页FIL_PAGE_TYPE_ALLOCATED0x0000最新分配还未使用的页FIL_PAGE_IBUF_BITMAP0x0005insert buffer 位图页FIL_PAGE_TYPE_SYS0x0006系统页FIL_PAGE_TYPE_TRX_SYS0x0007事务系统数据页FIL_PAGE_TYPE_FSP_HDR0x0008File Space Header 页FIL_PAGE_TYPE_XDES0x0009扩展描述页FIL_PAGE_TYPE_BLOB0x000ABLOB 页
2. Page Header
Page Header
用来记录数据页的状态信息,共占用 56 字节,具体信息如下表所示:
名称大小(字节)说明PAGE_N_DIR_SLOTS2表示页目录(Page Directory)中的槽(Slot)数量PAGE_HEAP_TOP2记录在页中是以堆的形式存放的,该值存放的是指向第一个记录的指针PAGE_N_HEAP2堆中的记录数,一共占用 2 个字节PAGE_FREE2指向可重用空间的首指针PAGE_GARBAGE2行记录中 delete flag 为 1 的总字节数,即被删除的记录的大小总和PAGE_LAST_INSERT2最后插入记录的位置PAGE_DIRECTION2最后插入的方向PAGE_N_DIRECTION2一个方向连续插入记录的数量PAGE_N_RECS2该页中记录的数量PAGE_MAX_TRX_ID8修改当前页的最大事务ID,注意该值仅在 Secondary Index 中定义PAGE_LEVEL2当前页在索引树中的位置,0x00表示叶节点PAGE_INDEX_ID8索引ID,表示当前页属于哪个索引PAGE_BTR_SEG_LEAF10B+ 树数据页非叶节点所在段的 segment headerPAGE_BTR_SEG_TOP10B+ 树数据页所在段的 segment header
3. Infimun Records 和 Supremum Records
Infimun 记录
是比该页中任何主键值都要小的值,
Supremum 记录
是比任何可能大的值还要大的值,这两个值在页创建时被建立,并且在任何情况下都不会被删除。这两个记录位于页中的所有航记录数据的收尾处,如图所示:
4. User Records
User Records
实际存储行记录的内容,如图:
5. Free Space
Free Space
指的是空闲空间,同样也是使用链表来进行组织的,在一条记录被删除后,该空间会被自动加入到空闲列表中
6. Page Directory
Page Directory
顾名思义是这个页的
所有记录的一个目录
,存放着
数量可变
的
记录指针
,这些指针指向页中存放的记录,有时
记录指针
被称为
槽
,所以
Page Directorty
有时被称为
目录槽
,在InnoDB页面中并不是一个记录指针对应一个记录,而是
若干个(1~8)
记录对应一个记录指针,在完整的页面中,每六条记录将有一个槽。
记录的头信息中有一个
大小为4位的n_owned
,表示管理当前记录的槽一共管理了多少个记录。
举例:如果一个页中的记录是‘A’、‘B’、‘F’、‘D’,记录指针将是(pointer to ‘A’)、(pointer to ‘B’)、(pointer to ‘D’)、(pointer to ‘F’)
由举例可知,指针的排列顺序是按照
键值的顺序
排列的,故在查找某一条记录时,可以通过
二分查找
的方式进行查找
所以查找一条记录的过程为:先在 B+ 树上定位到记录所在的叶子节点(数据页),然后将整个数据页载入到内存中,然后在目录槽中进行二分查找目标记录所在的槽,然后在槽所管理的若干条记录中寻找目标记录
7. File Trailer
为了检测页向磁盘中写入的过程中是否产生损坏,在 InnoDB 存储引擎页中设置了 File Trailer 来做检验。
File Trailer 组成:只有一个
FIL_PAGE_END_LSN
部分,占用 8 字节,前 4 字节代表此页的 checksum 值,最后 4 字节和 File Header 中的 FIL_PAGE_LSN 相同
检查原理:将 8 字节的 File Trailer 与 File Header 中的 FIL_PAGE_SPACE_OR_CHKSUM 和 FIL_PAGE_LSN 组成的 8 字节作比较(并不是简单的等值比较,而是需要通过检查 checksum 的算法)。
检查 checksum 的算法:通过参数
innodb_checksum_algorithm
来控制,可设置的算法有:crc32、none、strict_innodb、strict_crc32、strict_none,其中strict_*的算法表示严格按照设置的算法进行页的检测
MySQL [(none)]>show variables like'innodb_checksum_algorithm'\G;***************************1.row***************************
Variable_name: innodb_checksum_algorithm
Value: crc32
1rowinset,1 warning (0.08 sec)
是否开启对页的完整性检查由参数
innodb_checksums
控制:
MySQL [(none)]>show variables like'innodb_checksums'\G;***************************1.row***************************
Variable_name: innodb_checksums
Value: ON1rowinset,1 warning (0.00 sec)
版权归原作者 代码被吃掉了 所有, 如有侵权,请联系我们删除。