mysql innodb 表存储结构

1 逻辑存储结构

表空间-段-区-页

1.1 表空间

  • 共享表空间ibdata1 存放undo信息、系统事物信息、二次写缓冲
  • innodb_file_per_table ON打开后每一个table都有一个表空间,存放数据、索引、插入缓冲

1.2 段

数据段、索引段、回滚段

1.3 区

  • 每个区1M,由64个连续的页组成,每个页16K
  • 引擎最多每次可以申请4个区,保证数据的顺序性能

1.4 页

页结构
  • B+树索引本身并不能找到具体的一条记录,只能找到该记录所在的页,之后引擎把页加载到内存,通过PageDirectory再进行二叉查找

1.5 行

官网 https://dev.mysql.com/doc/refman/5.7/en/innodb-row-format.html#innodb-row-format-defining

行记录格式 innodb_default_row_format 默认 DYNAMIC

  • REDUNDANT
  • COMPACT
    768前缀字节+20字节指针 -> off page
  • DYNAMIC
    20字节指针 -> off page
  • COMPRESSED
    对off page内容进行zlib算法压缩(BLOB TEXT VARCHAR)

COMPACT

变长字段长度列表 NULL 记录头信息 隐藏列 字段1 字段2 字段n
  • 变长字段长度列表
    按列的顺序逆序排列,最多两个字节(所以varchar长度< 2^16-1=65535)
    待验证?

一个字节可以最多表示255,但是 MySQL 设计长度表示时,为了区分是否是一个字节表示长度,规定,如果最高位为1,那么就是两个字节表示长度,否则就是一个字节。例如,01111111,这个就代表长度为 127,而如果长度是 128,就需要两个字节,就是 10000000 10000000,首个字节的最高位为1,那么这就是两个字节表示长度的开头,第二个字节可以用所有位表示长度,并且需要注意的是,MySQL采取 Little Endian 的计数方式,低位在前,高位在后,所以 129 就是 10000001 10000000。同时,这种标识方式,最大长度就是 2^15 - 1 = 32767,也就是32 KB

  • NULL标志位
    逆序排列,二进制位标志(1是null,0不是null)
  • 记录头信息record header 5B
    next-recorder 下一行相对位置(所以在页中行就像一个链表)
  • 隐藏列
    rowid 6B
    事物id 6B
    回滚指针 7B

参考资料

https://blog.csdn.net/KouLouYiMaSi/article/details/101475473
https://blog.csdn.net/zhxdick/article/details/107049949
https://blog.csdn.net/qq_35590091/article/details/107361172

你可能感兴趣的:(mysql innodb 表存储结构)