免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1764 | 回复: 0
打印 上一主题 下一主题

MySQL 技术内幕:InnoDB存储引擎——读书笔记(四) [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-12-20 09:46 |只看该作者 |倒序浏览
InnoDB表结构
    未明确指定主键时:首先判断是否有非空的唯一索引(UNIQUE NOT NULL),若有则将其默认为主键,否则创建一个6字节的ROWID

4.1 逻辑存储结构:tablespace->segment->extent->page

  • 表空间是只增不减的,即使ROLLBACK后也并不收缩,而是标记为可用空间,供下次undo使用。
  • 数据段即B+树的页节点(leaf node segment),索引段即为B+树的非索引节点(non-leaf node segment)。
  • InnoDB存储引擎对于段的管理是由引擎本身完成的。表空间是由分散的页和段组成。
  • 由64个连续的页组成,每个页大小16KB,即每个区1MB。创建新表时,先有32页大小的碎片页(fragment page)存放数据,使用完后才是区(64个连续页)的申请。(InnoDB最多每次申请4个区,保证数据的顺序性能)
  • 类 型有:数据页(B-tree Node)、UNDO页(Undo Log Page)、系统页(System Page)、事务数据页(Transaction System Page)、插入缓冲位图页(Insert Buffer Bitmap)及插入缓冲空闲列表页(Insert Buffer Free List)等。

4.2 InnoDB行记录格式
1.Compact行格式

变长字段长度列表(1个或2个字节)

NULL标志位

记录头信息(5个字节)

1数据

2数据

……

    注:1.书中指明变长字段长度列表最多占2个字节是MySQLvarchar最大长度不超过65535的原因,指的是varchar列总长度应不超过65535,且需要考虑字符集因素(后文也提到了)

    2.NULL标志位的长度(n_nullable+7)/8 bytes(书中似乎排版有些问题)

表1 Compact行记录头信息

名称

大小(bit)

描述

()

1

未知

()

1

未知

Deleted_flag

1

该行是否已被删除

Min_rec_flag

1

1,如果该记录是预先被定义为最小的记录

N_owned

4

该记录拥有的记录数(the number of records owned by this record,没能搞明白到底指的啥意思)

Heap_no

13

索引堆中该条记录的排序记录

Record_type

3

记录类型000=普通  001=B+树节点指针  010=infimum  011=supremum  1xx=保留

Next_recorder

16

页中下一条记录的相对位置

 

2.Redundant行格式

字段长度偏移列表(1个或2个字节)

记录头信息(6个字节)

1数据

2数据

……

                 表2 Redundant行记录头信息

名称

大小(bit)

描述

()

1

未知

()

1

未知

Deleted_flag

1

该行是否已被删除

Min_rec_flag

1

1,如果该记录是预先被定义为最小的记录

N_owned

4

该记录拥有的记录数(the number of records owned by this record)

Heap_no

13

索引堆中该条记录的排序记录

N_fields

10

记录中列的数量(决定了表的列数最多为1023)

1byte_offs_flag

1

偏移列表为1个字节还是2个字节

Next_recorder

16

页中下一条记录的相对位置

     不管Compact或者Redundant,对于varchar中的NULL在列记录中只占NULL标志位,而不占实际存储空间;但是对于char中的NULL,两者的处理则是不同的:Compact格式下,charNULL同样不占存储空间,而Redundant下则是占存储空间的

    同时,行记录中还包括两个隐藏列:事务ID(6字节)和回滚指针列(7字节);若没有定义的Primary Key时,还会增加一个6字节的RowID列。

    InnoDB页内部是通过一种链表方式串联各个行记录的。

    InnoDB可以将一条记录中的某些数据存储在真正的数据页面之外,即作为行溢出数据,并将行溢出内容放入Uncompress BLOB Page。此做法保证了每页上至少有两行记录(否则失去了B+树的意义,变成链表了)

3.CompressedDynamic行记录格式

    InnoDB Plugin引入了新的文件格式Barracuda,对于存放BLOB的数据采用了完全的行溢出方式,在数据页只存储20个字节的指针,实际数据均存放在BLOB Page中。而之前的CompactRedundant会存放768个前缀字段在数据页。Barracuda中两种行记录格式:CompressedDynamic

    InnoDB通过Named File Formats机制来解决不同版本页结构兼容性的问题。不同页格式之间的关系如下:


    在多字节字符集的情况下,CHARVARCHAR的行存储(所需存储空间)基本是没有区别的,均是不定长。

 

4.3 InnoDB数据页(B-tree node)结构

    InnoDB数据页由七部分组成:

  • File Header:文件头( 38 bytes )
  • Page Header:页头( 56 bytes )
  • Infimum + Supremum Records:页中上/下界记录
  • Users Records:用户记录,即行记录
  • Free Space:空闲空间
  • Page Directory:也目录
  • File Trailer:文件结尾信息

                 表3 File Header(共38 bytes)

名称

大小(byte)

存储信息

FIL_PAGE_SPACE_OR_CHKSUM

4

页的CHECKSUM

FIL_PAGE_OFFSET

4

表空间中页的偏移量

FIL_PAGE_PREV

4

上一页/下一页(B+ Tree决定了叶子节点为双向列表)

FIL_PAGE_NEXT

4

FIL_PAGE_LSN

8

该页最后被修改的日志序列位置LSN

FIL_PAGE_TYPE

2

页类型

FIL_PAGE_FILE_FLUSH_LSN

8

"the file has been flushed to disk at least up to this lsn" (log serial number),仅在文件第一页有效

FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID

4

属于哪个表空间

 

                 表4 Page Header(共56 bytes)

名称

大小(byte)

存储信息

PAGE_N_DIR_SLOTS

2

页目录中slot()

PAGE_HEAP_TOP

2

堆中第一个记录的指针

PAGE_N_HEAP

2

堆中的记录数,最高bit位指明了行格式,0-Redundant1-compact

PAGE_FREE

2

指向空闲列表的指针

PAGE_GARBAGE

2

已删除记录(delete flag1)的字节数

PAGE_LAST_INSERT

2

指向最后插入记录的指针

PAGE_DIRECTION

2

最后插入方向。(会影响InnoDB效能)

PAGE_N_DIRECTION

2

一个方向上连续插入记录的数目

PAGE_N_RECS

2

该页中记录的数目

PAGE_MAX_TRX_ID

8

修改当前页的最大事务ID(仅在Secondary Index)

PAGE_LEVEL

2

当前页在索引树中的位置(0x00代表叶节点)

PAGE_INDEX_ID

8

当前页属于哪个索引ID

PAGE_BTR_SEG_LEAF

10

B+树叶节点中文件段的首指针位置

PAGE_BTR_SEG_TOP

10

B+树非叶节点中文件段的首指针位置


Page Directory:存放记录的相对位置

    InnoDB是一个稀疏目录sparse directory),即一个槽(slot)可能属于多个记录,最少属于4条记录,最多属于8条记录。

    Slot中记录按键顺序存放,以便可利用二叉查找迅速招到记录的指针。二叉查找的结果也只是一个粗略的结果,InnoDB必须通过recorder header中的next_record来继续查找相关记录。同时slot也解释了recorder headern_owned值的含义,即还有多少记录需要查找,因为这些记录并不包括在slots中。

    B+数索引本身并不能找到具体的一条记录,只能找到该记录所在的页。数据库把页载入内存,然后通过Page Directory再进行二叉查找

File Trailer只有一个FIL_PAGE_END_LSN部分8个字节。前4个字节代表该页的checksum值,最后4个字节和File Header中的FIL_PAGE_LSN相同,以此保证页的完整性。

http://forge.mysql.com/wiki/MySQL_Internals_InnoDB里面有一些额外的介绍】

 注:如若涉及版权或者其他问题,请联系本人。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP