InnoDB存储引擎是面向行的,也就是说数据是按照行进行存放的。常用的行记录格式有Compact和Redundant。
Compact行记录格式
Compact行记录的格式如下
变长字段长度列表 | NULL标志位 | 记录头信息 | 行1数据 | 行2数据 | … |
---|
1,非NULL变长字段列表
- 按照行的顺序逆序放置的
- 若行的长度小于255字节,用1字节表示
- 若行的长度大于255字节,用2字节表示
- 是因为VARCHAR类型最大长度限制为65535
2,NULL标志位
- 该位置指示了该行数据中是否有NULL值,有则用1表示。占1字节。
3,记录头信息(record header)
- 固定占用5个字节(40位)
- 由next_recorder可知,行记录在页内是通过一种链表结构串联起来。
InnoDB数据页结构
页是InnoDB存储引擎管理数据库的最小磁盘单位,页类型为B-tree Node存放的即是表中行的实际数据。
File Header (文件头)
- 主要用来记录页的一些头信息
- FIL_PAGE_PREV — 当前页的上一个页
- FIL_PAGE_NEXT — 当前页的下一个页
- FIL_PAGE_LSN — 该页最后被修改的日志序列位置LSN(Log Sequence Number)
- FIL_PAGE_TYPE — InnoDB存储引擎页的类型
Page Header (文件头)
- 记录数据页的状态信息
- PAGE_N_DIR_SLOTS — 在Page Directory(页目录)中的Slot(槽)数。
- PAGE_HEAP_TOP — 堆中第一个记录的指针,记录在页中是根据堆的形式存放的。
Infimum和Supremum Record
- 在InnoDB引擎下,每个数据页中有两个虚拟的行记录,用来限定记录的边界。
- Infimum记录是比该页中任何主键值都要小的值,Supremum 指比任何可能大的指还要大的值。
- 这两个值在页创建时被建立,并且在任何情况下不会删除。
User Record 和 Free Space
- User Record就是实际存储行记录的内容
- Free Space指空闲空间,同样也是个链表数据结构。在一条记录被删除后,该空间会被加入到空闲链表中。
Page Directory
- Page Directory(页目录)中存放了记录的相对位置,(这里存放的是页相对位置,而不是偏移量)。
- 这些记录指针成为Slots(槽)或目录槽(Directory Slots)
- 与其他数据库系统不同的是,在InnoDB中并不是每个记录拥有一个槽,InnoDB存储引擎的槽是一个稀疏目录(sparse directory),即一个槽中可能包含多个记录。
- 伪记录Infimum的n_owned的值总是1,记录Supremum的n_owned的取值范围为[1,8],其他用户记录的n_owned的取值范围为[4,8]。
- 由于Page Directory是稀疏目录,二叉查找的结果只是一个粗略的结果,因此InnoDB必须通过record header的next_record来继续顺序查找相关记录。
File Trailer
- 是为了检测页是否完整地写入磁盘。
- 只有FIL_PAGE_END_LSN属性,占8个字节,前4个字节表示该页地checksum,后4个字节和File Header里的FIL_PAGE_LSN相同。
- 将这两个值与File Header里的FIL_PAGE_SPACE_OR_CHKSUM和FIL_PAGE_LSN进行比较(checksum的比较是需要经过函数计算的),以此来保证页的完整性。
- 默认配置下,InnoDB每次从磁盘读取一个页就会检测该页的完整性。