1. 数据的文件名及作用
每创建一个数据库,都会在/var/lib/mysql/目录中创建一个database名的目录,其中表结构和表数据都存放在找个目录中
这个目录中会有三种文件类型
- opt: 存储数据库的默认字符集+字符校验规则
- frm:存储表结构
- ibd:存储表数据
2. 表空间文件结构
表空间由段(segment)、区(extent)、页(page)、行(row)组成
- 行:记录以行为单位进行存放
- 页:InnoDB 的数据是按「页」为单位来读写的,页大小为16kb,保证16kb连续空间(减少I/O次数)
- 区:b+树每层采用双向链表进行链接,可能页与页物理位置则不连续,随机I/O量提升,性能下降(一个区为1MB,存储64页,64页物理位置连续)
- 段:多个区组成,分为三种:数据段、索引段和回滚段
-
- 索引段:b+树非叶子节点的区的集合
- 数据段:b+树叶子节点的区的集合
- 回滚段:回滚数据的区的集合
3. InnoDB的行格式
行格式就是一条记录的存储结构,InnoDB有4种行格式,核心就是Compact行格式
3.1. 额外信息
- 变长字段字节数:变长字段真实数据字节数存储逆序存放在这里面
-
- eg:
-
- 变长字段字节数不是必须的,如果没有变长字段就没有
- eg:
- Null值列表:把Null值的列存储在Null值列表中,每个列对应一个二进制位,二进制位按照列的顺序逆序排列。
-
- 二进制位的值为
1
时,代表该列的值为NULL - 二进制位的值为
0
时,代表该列的值不为NULL。 - NULL 值列表必须用整数个字节的位表示(1字节8位),如果使用的二进制位个数不足整数个字节,则在字节的高位补
0
。
- 二进制位的值为
- 记录头信息
-
- delete_mask:标识数据是否被删,删除的时候这字段改为1
- next_record:下一条记录地址
- record_type:表示当前记录的类型,0表示普通记录,1表示B+树非叶子节点记录,2表示最小记录,3表示最大记录
3.2. 记录真实数据
三个隐藏字段:row_id,trx_id,roll_pointer
- row_id:建表时指定主键或唯一约束列,就没有row_id,占用6字节
- trx_id:记录事务id,版本控制使用,必需字段,6字节
- roll_pointer:记录上一个版本指针,mvcc相关字段,7字节
4. Mysql行溢出如何处理
Mysql磁盘和内存交互的基本单元是页,一页为16kb,也就是16384个字节,但是一列数据最大可以存储65532个字节,那应该如何处理呢?
如果一页存储不了一条数据就会发生行溢出的问题,多的数据会通过指针指向一个溢出页