InnoDB数据字典——字典表加载

  

1,介绍

  
 <代码>在InnoDB启动时,如果是新建数据库则需初始化库,需要创建字典管理的相关信息。函数innobase_start_or_create_for_mysql调用dict_create完成此功能,即创建数据字典,因为InnoDB系统表的个数结构固定,所以初始化库的时候只需要创建这几个表的B +树即可并将B +树的根页号存放到固定位置。对于B +树,只要找到根页面,就可以从根页面开始检索数据。相关系统表(即上一节讲到的4个系统表)在InnoDB内部,不会暴露给用户。
  
  4个系统表通过固定的硬编码进行构建。具体原理流程如下。 
  

2,数据字典创建及加载原理流程
 InnoDB数据字典——字典表加载“> <br/> 3,说明</p>
  <p> 1) innobase_start_or_create_for_mysql函数调用dict_create()函数进行数据字典的创建和加载工作。</p>
  <p> 2) dict_hdr_create完成系统表空间第7号页面dict头的初始化及创建SYS_TABLES两个索引,SYS_COLUMNS一个索引,SYS_INDEXES一个索引,SYS_FIELDS一个索引,其创建索引的函数是btr_create。</p>
  <p> 3)创建B +树索引后,通过dict_boot函数加载常驻内存的4个系统表。具体流程见流程图的②部分。</p>
  <p> 4)加载完成后,将这4个系统表挂在一个全局字典中:</p>
  </p> <p> dict0dict.h::
  <pre> <代码>/*词典系统结构体*/struct dict_sys_t {
  ib_mutex_t互斥对象;/* ! & lt;互斥锁保护的数据
  字典;保护的
  基于磁盘的词典系统表;
  这个互斥对象序列化创建表
  和删除表,以及阅读
  字典的数据表
  系统表*/row_id_t row_id;/* ! & lt;下一行id分配;
  注意,在一个检查站
  必须写关键字系统
  头和刷新到一个文件中;在
  这一定是来自复苏
  日志记录*/hash_table_t * table_hash;/* ! & lt;基于哈希表的表
  在名称*/hash_table_t * table_id_hash;/* ! & lt;基于哈希表的表
  在标识*/ulint大小;/* ! & lt;不同空间字节
  的表和数据字典
  索引对象*/dict_table_t * sys_tables;/* ! & lt;SYS_TABLES表*/dict_table_t * sys_columns;/* ! & lt;SYS_COLUMNS表*/dict_table_t * sys_indexes;/* ! & lt;SYS_INDEXES表*/dict_table_t * sys_fields;/* ! & lt;SYS_FIELDS表*//*=============================*/UT_LIST_BASE_NODE_T (dict_table_t)
  table_LRU;/* ! & lt;表的列表,可以驱逐
  从缓存中*/UT_LIST_BASE_NODE_T (dict_table_t)
  table_non_LRU;/* ! & lt;不能的表列表
  赶出缓存*/};</代码> </pre>
  <p>结构体中sys_tables, sys_columns, sys_indexes, sys_fields四个结构存储上述对应的4个系统表。</p>
  <p>结构体中哈希表及链表用来存储InnoDB中的所有表的缓存,包括系统表及用户表.table_hash哈希表按名字缓存,table_id_hash按表ID进行散列,LRU链表用来管理表对象缓存。</p>
  <p> 5)普通用户表加载流程见流程图的③、④部分。</p>
  <p>当用户访问一个用户表时,首先需要从表对象缓存中查找这个表的分享对象,如果找到则直接从其实例化表对象链表中拿一个使用,如果没有找的到,则需要重新打开这个表,需要找到这个表的字典信息。即③的流程。</p>
  <p>具体加载一个表的字典是④流程,dict_load_table的工作。</p>
  <p> a)首先需要找到SYS_TABLES表,也是先找缓存,缓存找不到再从系统表加载:dict_table_get_low </p>
  <p> b)找到之后构建一个查询键值,从SYS_TABLES的名字主键索引进行查询,如果诶呦找到或者该记录已经被删除则返回,否则解析找到的这条记录。然后根据这些信息创建表的内存对象表。</p>
  <p> c)加载列操作与加载表的原理基本一样,对应系统表的SYS_COLUMNS,聚集索引为(TABLE_ID POS),查找时,如果TABLE_ID相同,在POS从小到大排的序,所以构造所有列的键值时,只需要通过TABLE_ID查询即可,按顺序取出所有列信息一一构造内存对象。</p>
  <p> d)加载索引信息类似的流程</p><h2 class=InnoDB数据字典——字典表加载