上篇文章说了系统表空间的data dictionary header:
Data dictionary header(2) --系统表空间结构(三十四)
前面我们说了独立表空间和系统表空间:
独立表空间:
当在建立表的时候,在文件系统空间会生成同名的目录或者文件,一个页有16kb,我们都知道查询是通过b+树查找的,但如果数据太多,页之前又是通过双向链表查询的,物理空间不在一起,这时候查询就是随机I/O,为了两个页查询的距离不是很远,所以又有区的概念,64个页分为一个区,而256个区又分为一个组,所以当一个新表插入数据的时候,是根据区来插入的,区又属于段下面。
这时候就会问,如果新表的数据很少,根据区来划分不是很浪费空间吗,所以这时候innodb引入了碎片区的概念,当区存满32个的时候,才会升级属于特有的段,所以段里存放的是完全的区或者碎片区,区里面都是由extent descritor entry简称xdes entry管理,里面有四个链表,free,free_frag,full_frag,fseg四个链表,所以innoDB每次存入数据并不是遍历表空间里的数据,而是直接看free_frag链表是否有值,没有的话就是free链表申请,吧free链表升级为free_frag链表,当free_frag里的descritor entry已经没有空闲的数据页时候,就把这个xdes entry移动到full_frag里面,当有32个完整区时候 ,会吧区划分到属于他的段。
那怎么知道他属于什么段呢,因为xdes entry里面有segment id,用段id划分肯定是不行的,因为当前段里肯定有没有存满的碎片区,如果按full_frag肯定也不行,这个链表里面的数据是属于不同的段,不可能吧里面所有的数据都划分到同一个段。
所以fseg链表又分为三个链表,段的free链表,not_full链表,和full链表,当数据存满的时候先看看not_full链表是否可以继续存储数据,不可以就去段的free链表申请,当满了就放进full链表。
叶子节点和非叶子节点又分为不同的段,一个表中,如果有聚簇索引和二级索引,一个索引会生成两个段,两个索引有四个段,四个段有12个链表,再加上表空间直属的三个链表,free,free_frag,full_frag,所以会有15个链表。
段里面管理段的是inode entry,里面和区的xdes entry类似,有三个链表free,not_full,和full。
区的名称又分为extent0,extent1等等,而 extent0第一页叫FSP,以后的区空间第一页都叫xdes 类型页面管理者 xdes entry,而fsp和xdes类似,存放着xdes 的各种链表,一共4个,但多了几个表空间特有的属性 。
比如file space header,这个是重点,放着表空间直属管理的东西,比如多少个页面,初始化前后的值等,还存着区链表的基点和段链表的基点,方便后面查找。
Fsp里面还有一个inode类型页,里面放啥前面都说过了,分别有着三个链表。
系统表空间:
系统表空间总体来说和独立表空间类似,但系统表空间存着系统特有的页面,是表空间之首,space id为0。
着重介绍data dictionary header,这里面有什么呢,都是全局的唯一id自增数据,当index,table,space,row_id等新增的时候,都是在这里取值,然后在吧这里的最大值加1。
还存放着系统表数据,sys_tables,sys_cloums,sys_indexes,sys_fileds。
innoDB有这四个字典表,基本所有的数据都能获取到,通过表名在tables里获取到tableid,通过tableid可以从colums获取到表列的数据,从indexes获取到index id,通过index id可以从fileds获取到索引列的信息。
而这些数据是不能直接访问的,mysql为了方便我们排查错误,给了innodDB_sys类型的表,可以在information_schema里查询这些数据方便排查问题。