文章目录结构
区、段、碎片区和表空间
- 什么是区?
- 什么是段?
- 什么是碎片区?
- 什么是表空间?
在上文 InooDB 存储行格式一文中已经大致讲述过,再来回顾一下,直接上图:
名词解释如下:
- 行(row): 数据库中的数据都是按行(row)存储的,行记录(统称)根据不同的
行格式
,有不同的存储结构。 - 页(page): 记录是按行存储的,但是数据库的读取并不是以
行
为单位,而是以页
为单位,每页的大小为 16KB
,否则读取一次只能读取一行数据(也就是一次 I/O 操作),只能处理一行数据,效率太低了。 - 区(extent): B+Tree 的每一层的节点之间都是通过双向链表链接的,以页为单位,相邻的两个页之间位置并不是连续的,可能离的非常远,那么数据量大的情况在查询的时候就会产生大量的随机 I/O 操作(效率低)。为了解决这个问题,为某个索引分配空间的时候按照
区
为单位,一个区的大小为1MB
,对于16KB
大小的页来说,连续的64
个页划分为一个区
,这样就使得相邻的页的物理位置也是相邻的,就可以使用顺序 I/O
了。 - 段(segment): 表空间由多个段组成,段是由多个区组成。段一般分为
数据段
、索引段
和回滚段
等。
-
- 数据段:存放 B+Tree 叶子节点区的集合
- 索引段:存放 B+Tree 非叶子节点区的集合
- 回滚段:存放回滚数据区的集合(MVCC 就是利用了回滚段实现了多版本查询控制)
- 表空间(Tablespace): 是一个逻辑容器,表空间存储的对象是段,在一个空间中可以由一个段或多个段,但是一个段只能属于一个表空间。
为什么要有区?
B+Tree
的每一层的节点之间都是通过双向链表链接的,以 页为单位
为单位分配存储空间,相邻的两个页之间位置并不是连续的,可能离的非常远。
B+Tree 索引适用的场景提到在范围查询时,只需要定位到最左边和最右边的记录(顺序存储),然后沿着双向链表一直扫描就可以了,而如果链表中相邻的两个数据页的物理位置相差的很远,中间的查询产生的就是 随机 I/O
。
磁盘的速度和内存的速度差了好几个量级, 随机 I/O 是非常慢的
。
为了能够使用 顺序 I/O
,尽量让链表中相邻的页的物理位置也相邻,这就引入了 区
的概念,一个区在物理位置上就是连续的 64 个页
。因为 InooDB 的一个页默认大小为 16KB
,所以一个区的大小为 1MB
。
在表中数