InnoDB的表空间也是体现了作者浓浓的设计思考啊,提高向表空间插入数据的效率又不至于浪费太多的空间,最大化效率,最大化节省空间,简直完美。
一、页面类型
InnoDB是以页为单位管理存储空间的,聚簇索引和其他的二级索引都是以B+树的形式存放到表空间的,B+树的数据项就是数据页。
二、页面数据结构
任何类型的页都包含以下两个部分:
- File Header:占用38个字节,记录页面的一些通用信息
- File Trailer:占用8个字节,校验页是否完整,保证从内存到磁盘刷新时内容的一致性
biao表空间中的每一个页都对应着一个页号,也就是FIL_PAGE_OFFSET,这个值存放在File Header中,占用File Header中4个字节,也就是32个比特位,所以一个表空间最多支持64TB的数据。
三、区的概念
页组成区(extent),区是为了管理表空间中的区的,对于16KB的页来说,连续的64个页就是一个区,也就是说一个区默认占用1MB空间大小,每256个区被划分为一组。
即1组 = 256区,1区 = 64页
- 第一个组最开始的三个页面的类型是de固定的,也就是说 extent 0这个区最开始的3个页面类型是固定的,分别是:
- FSP_HDR 类型:这个类型的页面是用来登记整个表空间的一些整体属性以及本组所有的区。
- IBUF_BITMAP 类型:这个类型的页面是存储本组所有区的所有页面关于INSERT BUFFER的信息。
- INODE 类型:这个类型的页面存储了许多称为INODE的数据结构。
- 其余各组最开始的2个页面的类型是固定的,分别是:
- XDES 类型
- IBUF_BITMAP 类型
为什么引入区的概念?
有了页为什么还要引入区呢?难道是作者故弄玄虚吗?不是的,每一个概念的引出都是有其使用场景的。
原因主要有以下几点:
如果我们表中数据量很少时,确实用不着区,因为简单几个页就能对数据进行管理,但是数据一多呢,这时我们就需要考虑采用更高效的管理方式。但是不引入区的概念一点不影响存储引擎的运行,但是我们考虑下面的一个场景:
- 我们每向表中插⼊⼀条记录, 本质上就是向该表的聚簇索引以及所有⼆级索引代表的B+树的节点中插⼊数据。 ⽽B+树的每⼀层中的⻚都会形成⼀个双向链表, 如果是以⻚为单位来分配存储空间的话, 双向链表相邻的两个⻚之间的物理位置可能离得⾮常远。 我们介绍B+树索引的适⽤场景的时候特别提到范围查询只需要定位到最左边的记录和最右边的记录, 然后沿着双向链表⼀直扫描就可以了, ⽽如果链表中相邻的两个⻚物理位置离得⾮常远, 就是所谓的随机I/O。 再⼀次强调, 磁盘的速度和内存的速度差了好⼏个数量级, 随机I/O是⾮常慢的, 所以我们应该尽量让链表中相邻的⻚的物理位置也相邻, 这样进⾏范围查询的时候才可以使⽤所谓的顺序I/O。
四、段的概念
待更新…