当前位置:网站首页>MySQL之InnoDB引擎(五)
MySQL之InnoDB引擎(五)
2022-07-26 19:22:00 【uesowys】
1 InnoDB介绍
2 InnoDB架构
2.1 内存存储架构
2.1.1 缓冲池(Buffer Pool)
2.1.1.1 缓冲池LRU算法
2.1.1.2 缓冲池配置
2.1.1.3 监控缓冲池
2.1.2 缓冲变化(Change Buffer)
2.1.2.1 索引类型介绍
2.1.2.2 缓冲变化定义
2.1.2.3 缓冲变化配置
2.1.2.4 最大空间配置
2.1.2.5 缓冲变化监控
2.1.3 适应性哈希索引(Adaptive Hash Index)
2.1.4 缓冲日志(Log Buffer)
2.2 磁盘存储架构
2.2.1 数据表(Tables)
2.2.1.1 数据表的创建
2.2.1.2 外部表的创建
2.2.1.3 导入表数据文件
2.2.1.4 移动或者复制数据表
2.2.2 数据行的物理结构
2.2.2.1 字段起始偏移量
2.2.2.2 扩展字节
2.2.2.3 字段内容
2.2.3 数据页的物理结构
InnoDB存储数据表的行记录在固定大小的存储单元中,该存储单元被称之为页(page),有时页被称之为块(block),目前页的默认大小是16kb,InnoDB存取数据是以多页的方式操作。一数据页的物理结构由多个部分组成,其中包括很多数据行的记录,也包括该页的头部以及页的尾部。本章节将描述数据页的物理结构。
一个数据页由以下七个部分组成。
2.2.3.1 Fil Header
数据页文件的头部结构由8个部分组成,如下所示:
FIL_PAGE_SPACE |
大小:4字节 该部分表示页所在的数据表的ID标识,不同的数据页属于不同的数据表(如前面所述,总表空间中可能包括多个数据表的数据,所以需要标识页所属的数据表),其中SPACE是指日志或者表空间 |
FIL_PAGE_OFFSET |
大小:4个字节 从存储空间开始位置的顺序页号(偏移量) |
FIL_PAGE_PREV |
大小:4字节 上一页的位置偏移量 |
FIL_PAGE_NEXT |
大小:4字节 下一页的位置偏移量 |
FIL_PAGE_LSN |
大小:8字节 页的最近日志记录的日志系列号 |
FIL_PAGE_TYPE |
大小:2字节 页的类型,类型包括:FIL_PAGE_INDEX(索引页), FIL_PAGE_UNDO_LOG(重做日志页), FIL_PAGE_INODE(内节点页), FIL_PAGE_IBUF_FREE_LIST(空闲列表页) |
FIL_PAGE_FILE_FLUSH_LSN |
大小:8字节 到该序列号为止已经被刷到磁盘的日志序列号 |
FIL_PAGE_ARCH_LOG_NO |
大小:4字节 最近已经归档的日志文件数(在FIL_PAGE_FILE_FLUSH_LSN日志序列号被刷到磁盘的时刻) |
根据以上的结构,下图展示索引的物理结构的叶子节点的关系(B+tree):

如上图所示,InnoDB的索引结构使用的是非二叉树结构,其使用优化的变异的B-tree结构,被称之为B+tree。在传统的二叉树结构遍历算法中,查找下一子节点,需要重新回到上级节点,再从上级节点往子节点查找。而InnoDB为了提高查询性能,在所有的叶子节点中提供叶子节点之间的指针,可以指向下一叶子节点或者指向上一叶子节点,而不用向上级节点查找,该算法简化了叶子节点的遍历算法,提高了查询的效率。(InnoDB的数据记录是存储在叶子节点中,非叶子字节不存储数据记录)
由以上的页的物理结构可知,InnoDB的数据记录与日志记录相关,也就是数据表空间与重做日志相关,因为每个数据记录的增加、删除、修改操作都与事务相关,事务操作失败,需要执行事务回滚操作,这些操作都需要依靠数据页中记录的信息。
2.2.3.2 Page Header
页的头部结构由14个部分组成,如下所示:
PAGE_N_DIR_SLOTS |
大小:2字节 指针槽的数量,每个指针槽指向不同的记录 |
PAGE_HEAP_TOP |
大小:2字节 指向堆中的第一条记录的指针 |
PAGE_N_HEAP |
大小:2字节 堆中记录的数量,默认值等于2 |
PAGE_FREE |
大小:2字节 指向第一个空闲记录的位置的指针,也就是,该记录已经被删除或者被合并了,则该空闲的记录保存在一个单向链表,该空闲指针指向该链表的第一条记录位置,下一指针(上一章节数据行的物理结构中的扩展字段)指向该链表的下一记录 |
PAGE_GARBAGE |
大小:2字节 已经删除的记录的总字节数 |
PAGE_LAST_INSERT |
大小:2字节 指向最后插入的记录的位置的指针 |
PAGE_DIRECTION |
大小:2字节 指针的方向,包括PAGE_LEFT(指向左边), PAGE_RIGHT(指向右边), PAGE_NO_DIRECTION(无指向),一般情况下,用于判断记录插入操作是否是升序排列,有助于提升InnoDB的存取效率 |
PAGE_N_DIRECTION |
大小:2字节 在相同方向上连续插入记录的数量,例如,最后插入的n条记录都是往左边方向的 |
PAGE_N_RECS |
大小:2字节 用户数据记录的数量 |
PAGE_MAX_TRX_ID |
大小:8字节 当前页的更新的数据记录事务中的最大的事务ID(该事务ID只对非主键索引有效) |
PAGE_LEVEL |
大小:2字节 该页在索引树中的级数,叶子节点的级数是0 |
PAGE_INDEX_ID |
大小:8字节 该页所属的索引ID |
PAGE_BTR_SEG_LEAF |
大小:10字节 B-tree索引树中的叶子节点所属页的数据文件的段的头部(包括空间ID、页的序号、字节的偏移量),用于为新的数据页申请存储空间 |
PAGE_BTR_SEG_TOP |
大小:10字节 B-tree索引树中的非叶子节点所属页的数据文件的段的头部包括空间ID、页的序号、字节的偏移量),用于为新的数据页申请存储空间 |
2.2.3.3 Limits of Records
Infimum表示的下确界,Supremum表示的是上确界,属于数学的概念。
该部分包括记录集合的最大下确界以及最小上确界,在InnoDB开始建立第一条索引的时候,会确定主键值的范围,所有的索引的主键值不能小于最大下确界,也不能大于最小下确界。执行索引检索的时候,主键值的检索范围也不能超出此范围。
在索引刚创建的时候,B-tree索引结构的根节点中保存,当记录逐渐增多的时候,最大下确界保存在最小的叶子节点中,最小上确界保存在最大的叶子节点中。
2.2.3.4 User Records
在数据页中,该部分保存的是用户插入的数据记录。
保存在该部分中的数据记录是有序或者无序或者部分有序,InnoDB插入记录的时候不以索引的顺序存储,而是直接在已存在的记录后面保存新的记录、或者在已删除的记录位置中保存新的记录。虽然,保存在页中的数据记录无序,但是B-tree索引检索数据的时候是按照顺序检索的,检索操作使用每个记录中的记录指针(上一章节中数据行的物理结构中的扩展字段),该记录指针按照索引的顺序指向一下数据记录的位置,这是一个用于索引检索的有序的单向链表。
2.2.3.5 Free Space
该部分是空闲空间,不断增长用于保存新的记录。
2.2.3.6 Page Directory
该部分保存页的目录,在目录中包括多个指针,指针的数量可变化,该部分也被称之为槽或者目录槽。一般情况下,每个目录槽包括6条记录,其中槽的记录是逻辑上有序的,也就是,每个记录是按照记录键的值排序,而不是按照存储的地址位置排序。例如,对于记录(A B F D),目录槽的逻辑顺序是(指针-A 指针-B 指针-D 指针-F),其中每个槽的大小固定,使用目录槽可以实现快速的二分查找。因为不是每条记录对应一个目录槽,所以,还需要使用数据记录中的扩展字段作为指针实行多行数据记录的检索。
2.2.3.7 Fil Trailer
该部分表示数据页的文件的尾部。
FIL_PAGE_END_LSN |
大小:8字节 前面的4个字节表示当前页的校验和,后面的4个字节表示页文件头部的字段FIL_PAGE_LSN。校验和是为了保证页数据的完整性,虽然InnoDB使用日志恢复也能保证数据的完整性,例如数据的页文件写一半的时候发生宕机,需要使用重做日志恢复数据,但是使用当前页的校验和更能保证数据的完整性。其中FIL_PAGE_LSN字段填充后面部分的4个字节,主要是为了保证页数据的前后一致性。 |
2.2.3.8 数据页示例
从InnoDB的实际的数据文件中获取数据页的片段如下所示:

根据以上的数据页的片段,分析如下所示:
在以上的数据页文件中,忽略从开始计算的38个字节的偏移量,该38个字节是Fil Header |
00 05 |
名称:PAGE_N_DIR_SLOTS 该字节码表示5个指针槽(参考Page Directory部分的说明) |
02 F5 |
名称:PAGE_HEAP_TOP 当前是指向页开始的空闲位置的地址是0402F5 |
00 12 |
名称:PAGE_N_HEAP 表示当前页中保存18条记录(12是十六进制) |
00 00 |
名称:PAGE_FREE 表示当前页没有空闲的记录位置(已经被删除的记录) |
00 00 |
名称:PAGE_GARBAGE 表示当前页没有空闲的字节(已经被删除的记录的总字节) |
02 E1 |
名称:PAGE_LAST_INSERT 最近插入的记录的位置02E1 |
00 02 |
名称:PAGE_DIRECTION 2表示类型PAGE_RIGHT |
00 0F |
名称:PAGE_N_DIRECTION 表示最近插入的15条记录是向右升序的(PAGE_RIGHT) |
00 10 |
名称:PAGE_N_RECS 表示当前页中保存16条用户插入的记录 |
00 00 00 00 00 00 00 |
名称:PAGE_MAX_TRX_ID 表示事务id |
00 00 |
名称:PAGE_LEVEL 0表示当前页是叶子节点 |
00 00 00 00 00 00 00 14 |
名称:PAGE_INDEX_ID 表示当前页在索引中的序列号是20 |
00 00 00 00 00 00 00 02 16 B2 |
名称:PAGE_BTR_SEG_LEAF 表示头部信息 |
00 00 00 00 00 00 00 02 15 F2 |
名称:PAGE_BTR_SEG_TOP 表示头部信息 |
(未完待续)
边栏推荐
- 银行业概览
- 一文读懂 .NET 中的高性能队列 Channel
- regular expression
- 金仓数据库 KingbaseES SQL 语言参考手册 (19. SQL语句: DROP TABLE 到 LOAD)
- Kingbases SQL language reference manual of Jincang database (15. SQL statement: create materialized view to create schema)
- 2000字助你精通防抖与节流
- Design of intelligent weighing system based on Huawei cloud IOT (STM32) [i]
- 低代码工具有哪些特色?明眼人都能看出来的低代码两大发展轨迹!
- [shell] Reprint: batch replacement find awk sed xargs
- 网红辣条抓不住年轻人
猜你喜欢

UE5编辑器Slate快速入门【开篇】

罗永浩赌上最后一次创业信用

Read the high-performance queue channel in.Net

Leetcode daily practice - 189. Rotation array

一文读懂 .NET 中的高性能队列 Channel

go+mysql+redis+vue3简单聊室,第6弹:使用vue3和element-plus调用接口

Software testing - what are the automated testing frameworks?

Docker使用mysql:5.6和 owncloud 镜像,构建一个个人网盘,安装搭建私有仓库 Harbor

ShardingSphere-JDBC 关键字问题

Analysis of interface testing
随机推荐
花1200亿修一条“地铁”,连接4个万亿城市,广东在想啥?
Student‘s t分布
STM32F103有源蜂鸣器驱动程序
Decompile jar files (idea environment)
LeetCode_回溯_中等_216.组合总和 III
Solution to the third game of 2022 Niuke multi school league
网络与VPC动手实验
【MySQL】 - 索引原理与使用
go+mysql+redis+vue3简单聊室,第5弹:使用消息队列和定时任务同步消息到mysql
Use request header authentication to test API interfaces that need authorization
试用了多款报表工具,终于找到了基于.Net 6开发的一个了
three. Two methods of making Earth annotation with JS
静音台式风扇芯片-DLTAP703SD-杰力科创
同花顺靠谱吗?我刚开始学习理财,开证券账户安全吗?
数据库笔记(来自老社)
使用请求头认证来测试需要授权的 API 接口
Kingbases SQL language reference manual of Jincang database (16. SQL statement: create sequence to delete)
svn使用碎碎念
2000 words to help you master anti shake and throttling
.NET GC工作流程