阅读inndob page directory相关文档

This commit is contained in:
2025-02-03 17:38:20 +08:00
parent 049240dc16
commit 92658eb0b1

View File

@@ -161,14 +161,47 @@ page directory页目录中存放了记录的相对位置这些记录指
在slots中记录按照索引键值顺序存放可以通过二叉查询迅速找到记录的指针。
由于在innodb存储引擎中page directory是稀疏目录二叉查找结果只是一个粗略的结果
由于在innodb存储引擎中page directory是稀疏目录二叉查找结果只是一个粗略的结果innodb存储引擎必须通过record header中的next_record来继续查找相关记录。
#### B+树索引
<img src="//cloud.mo4tech.com/images/ldWYtlmLrJXYtJXZ0F2dtA3YmBnYmFTdzsWL2xGc05XYhR2MwIjZycTMyczN4gDOmBTY0Y2Y5QmYygjY1YTNk9CcjZGciZWM1NzatkWLuNWLz9Gdv02bj5yZtlWZ0lnYu4WaqVWdq1iNw9yL6MHc0RHa/cefbe79c0791cd0781f7c6aa3a923e21.image" data-cdn="">
如上图所示innodb中的数据是按照索引来进行组织的。但是通过B+树索引,其无法直接查询到指定的记录,其只能查询到记录所位于的页。
例如,在上图示例中,其在查询`ID=32`的时只能查询到该记录位于page 17中。
> 在B+树的叶子节点每个页的File Header中都存有指向前一个页和后一个页的指针`故而每个页之间是通过双向列表结构来维护的`;但是对于页中的记录,`记录与记录之间维维护的时单向列表的关系`。
>
> 对于Compact或Dynamic行格式的页其每条记录的record header中都包含一个next_record字段指向下一条记录。故而位于同一个页中的记录可以单向访问。
但是在一个页内查找某条记录时沿着单向链表进行查找其效率很低。故而page中的数据时机被分为了多个组被分为的组构成了一个subdirectory故而通过子目录能够缩小查询范围提高查询性能。
page directory是一个能够存储多个slots的部分每个slot中存储了group中最后一条记录的相对位置。假设slot中最大一条记录为`r`那么group中记录的条数被存储在`r`记录record header的`n_owned`字段中。
group中record的数量约束如下
- infimum group中records数量限制为`[1,8]`
- supremum group中records数量限制为`[1,8]`
- 其他group中records限制为`[4,8]`
page directory生成过程如下所示
- 最开始时页中只有infimum和supremum两条记录它们分别属于两个group。page directory中有两个slots指向这两条记录两个slot的n_owned都为1
- 后续当新的记录被插入页时系统会查找page directory中主键值大于待插入记录的第一个slot。slot对应最大记录的`n_owned`字段会增加1代表group中新插入了记录直到group中的记录数量到达8
- 当新纪录被插入到的group中记录数大于8时group中的记录被分为2个group一个group包含4条记录另一个group包含5条记录。该过程将会向page directory中新增一个新的slot
- 当记录被删除时slot最最大一条记录的`n_owned`将会减少1当n_owned字段小于4时会触发再平衡操作平衡后的page directory满足上述要求
page directory中的slots数量如page header中的`PAGE_N_DIR_SLOTS`所示。
一旦innodb中页包含page directory后其会通过二分查找快速的定位slot并且从group中最小记录开始通过`next_record`指针来遍历页中的记录列表。这样能够快速的定位记录位置。
### File Trailer
#### 完整性校验
在innodb中页的大小为16KB可能和磁盘的扇区大小不同。通常磁盘的扇区大小为512字节故而在写入一个页到磁盘中时需要分32个扇区进行写入。
在写入一个页时可能会发生宕机场景这时一个页只写入了一部分可能会发生脏写。此时可以通过double write buffer机制对脏写的页进行恢复。
在一个页被写入到磁盘中时首先会被写入的是File Header的`FIL_PAGE_SPACE_OR_CHKSUM`,该部分是page的checksum。
innodb设置了File Trailer部分来校验page是否被完全写入到磁盘中File Trailer中只包含一个`FIL_PAGE_END_LSN`部分占用8字节前4字节代表该页的checksum值后4字节和File Header中的`FIL_PAGE_LSN`相同,`代表最后一次修改该页关联的LSN位置`。将上述两个字段和File Header中的`FIL_PAGE_SPACE_OR_CHKSUM``FIL_PAGE_LSN`值进行比较,查看是否一致,从而保证页的完整性。
默认情况下在innodb每次从磁盘读取page时都会检查页面的完整性。