阅读 280

MySQL技术内幕InnoDB存储引擎阅读相关笔记-InnoDB基本介绍-存储结构

一、InnoDB存储引擎主键

​ 如果在创建表的时候没有显示的定义主键(primary key),则InnoDB存储引擎会按如下方式创建主键。

​ 首判断表中是否有非空的唯一索引,如果有则该列即为主键

​ 不符合上面条件,则InnoDB会默认自动创建一个指针(6个字节)

二、InnoDB逻辑存储结构

1、整体介绍

​ InnoDB所有数据都被逻辑地存放在一个空间中,称之为表空间(tablespace),也就是.ibd文件,所以其是有共享表空间以及每个表独立的表空间。

​ 表空间又由段(segment)、区(extent)、页(page)组成,页在有些文档也被称为块(block)

2、表空间

​ 表空间可以看为是InnoDB存储引擎逻辑结构的最高层,所有的数据都是存放在表空间中,同时可以通过innodb_file_per_table来让每个表都有自己独立的表空间。

​ 每张表独立的表空间存放的只是数据、索引、插入缓冲,其他的例如Undo信息,系统事务信息、二层写缓冲等还是存放在原来的共享表空间中,即默认的ibdata1文件。

3、段

​ 表空间是由各个段组成的,常见的段有数据段、索引段、回滚段。同时由于InnoDB存储引擎是索引组织的(index organized),则时间段即为B+树的页节点(上图的 leaf node segment),索引段即为B+树的非索引节点(non-leaf node segment)。

​ 需要注意的是,并不是所有对象都有段,所以可以理解为表空间是由分散的页与段共同组成的。

4、区

​ 区是由64个连续的页组成的,每个页是16KB,所以每个区是1MB。对于大的数据段,InnoDB存储引擎每次最多可以申请4个区,以此来保证数据的顺序性能。(连续的页,所以InnoDB在申请内存空间的时候,是按区申请的?)

5、页

​ 页是InnoDB进行磁盘管理的最小单位。常见的页类型有:

​ 数据页(B-true Node)

​ Undo页(Undo Log Page)

​ 系统页(System Page)

​ 事务数据页(Transaction system Page)

​ 插入缓冲位图页(Insert Buffer Bitmap)

​ 插入缓冲空闲列表页(Insert Buffer Free List)

​ 未压缩的二进制大对象页(Uncompressed BLOG Page)

​ 压缩的二进制大对象页(Compressed BLOG Page)

6、行

​ InnoDB是面向行的,也就是说数据的存放是按行进行存放的。书上写的是每个也存放的行是有规定的,最多是7992行记录。

三、InnoDB物理存储结构

1、整体介绍

​ 从物理意义来看,InnoDB表是由共享表空间(ibdata1文件)、日志文件组也就是Redo文件组(默认的ib_logfile0ib_logfile1文件)、表结构定义文件(.frm文件,这个是与mysql相关的,其他的引擎也有这个文件)。开启innodb_file_pre_table的话,就还有每个表的独立表空间(.ibd文件),其存储数据、索引、表的内部数据字典。

四、InnoDB行记录格式

​ 记录在页中是保存表中一行行数据。可以通过show create table xxx\G来查看

​ 可以看到这里的Row_format行格式是Dynamic(书上是以Compact格式为例,不过各种格式整体记录的核心信息应该大同小异的)

1、Compact行记录格式

1)、变长字段长度列表

​ 其是用来表示变长字段的,当列的长度小于255未的时候用1字节表示,大于用两个字节表示,也就解释了varchar类型最大长度是65535(但实际是小于这个数的,因为还有别的默认的开销)。

2)、NULL标志位

该位表示此行数据是否有NULL值,用1表示。

3)、记录头信息

4)、列数据

​ 这个就是用来存储实际每列具体的数据。这里需要注意的是NULL值是不该部分任何数据的,其只有NULL标识位表示。同时每行数据除了用户定义的列外,还有两个隐藏列,事务ID列与回滚指针列。并且如果没有对应规则的主键,每行会增加一个默认的RowId列。

​ 然后书上还有介绍Redundant行记录格式,这个就不介绍了。

2、行溢出数据

​ InnoDB存储引擎可以将一条记录中的某些数据存储在真正的数据页面之外,即作为行溢出数据。一般的BLOBLOB这种大对象列类型可能会发生。但其实其会看数据存储的数据大小,也可能不会发生,书上是以varchar这种类型举例,varchar类型也可能会行溢出数据。如果sql_mode设置为严格模式的话,可能会有警告,设置varchar大小为65535。这个sql_mode其实就是可以设置对列这些进行严格模式进行校验,可以去具体了解下。

五、InnoDB数据页结构

​ 通过前面的介绍我们知道,页类型为B-tree node的页,其存放的就是表中行的实际数据。

1、数据页组成

2、File Header

File Header是用来记录页的一些头信息,由8个部分组成:

1)、FIL_PAGE_SPACE_OR_CHECKSUM

​ 表明该页属于哪个表空间,这是因为如果没有开启innodb_file_per_table,所有表信息都是放在idbdata1文件,所以就需要建立对应页的表空间。

2)、FIL_PAGE_OFFSET

​ 表示表空间中页的偏移量

3)、FIL_PAGE_PREV、FIL_PAGE_NEXT

​ 表示当前页的上页及下页

4)、FIL_PAGE_LSN

​ 表示该页最后被修改的日志序列位置LSN(Log Sequence Number)。这个是用来校验页数据的,后面会有介绍

5)、FIL_PAGE_TYPE

​ 表示页的类型,一般取值有:

6)、FIL_PAGE_FILE_FLUSH_LSN

​ 该值仅是数据文件中的一个页中定义,代表文件至少被更新到了该LSN值

7)、FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID

​ 该值表示页归属于哪个表空间。

3、Page Header

​ 其是用来记录数据页的状态信息,由14个部分组成

1)、PAGE_N_DIR_SLOTS

​ 在Page Directory(页目录)中的Slot(槽)数。Page Directory中存放了记录的相对位置

2)、PAGE_HEAP_TOP

​ 堆中第一个记录的指针。

3)、PAGE_N_HEAP

​ 堆中的记录数

4)、PAGE_FREE

​ 指上空闲列表的首指针

5)、PAGE_GARBAGE

​ 以删除记录的字节数。即行记录结构中,delete_flage为1的记录大小的总数

6)、PAGE_LAST_INSERT

​ 最后插入记录的位置

7)、PAGE_DIRECTION

​ 最后插入的方向

8)、PAGE_N_DIRECTION

​ 一个方向连续插入记录的数量

9)、PAGE_N_RECS

​ 该页中记录的数量

10)、PAGE_MAX_TRX_ID

​ 修改当前页的最大事务ID,该值仅在Secondary Index定义

11)、PAGE_LEVEL

​ 当前页再索引树中的位置。0x00表示节节点

12)、PAGE_INDEX_ID

​ 当前页 属于哪个索引ID

13)、PAGE_BTR_SEG_LEAF

​ B+树的页节点中,文件段的首字节位置。该值仅在B+树的Root页中定义

14)、PAGE_BTR_SEG_TOP

​ B+树的非叶节点中,文件段的首指针位置。该值仅在B+树的Root页中定义。

4、Infimun与Supremun记录

每个数据页中有两个虚拟的行记录,用来限定记录的边界。Infimun记录比该页中任何主键都要小的值,Supremun是都要大

5、User Records与FreeSpace

​ User Records是实际存储行记录的内容。FreeSpace是空闲空间,是链表数据结构。当一条记录被删除后,该创建就会天骄到空闲链表中。

6、File Trailer

​ 为了保证页能够被完整写入磁盘,InnoDB存储引擎的页中设置了File Trailer部分。该值只有FIL_PAGE_END_LSN部分,8字节。前4给字节表示该页的checksum值,后4个字节与前面File Header中的FIL_PAGE_LSN相同。通过这两个值的比较是否相同,来保证页的完整性。

文章分类
后端
文章标签