首页 > 代码库 > Innodb加载数据字典 && flush tables

Innodb加载数据字典 && flush tables

测试了两个case,属于之前blog的遗留问题:

  1.   innodb如何加载数据字典
  2.   flush tables都做了什么操作

 

先来看下innodb加载数据字典:

  首次使用:select * from tt;

 

1. 创建handler对象

函数调用栈:
  open_binary_frm
    get_new_handler
      innobase_create_handler
        ha_innobase::ha_innobase

  根据单实例 handlerton + table_share两个参数,创建了handler对象,赋值table->file。server层对innodb的操作,都通过这个接口完成。

 

 

2. open innobase_share

  innobase_share是innodb层对某张表的定义,全局共享结构, 受 innobase_share_mutex保护。

  innobase_open_tables hash表保存着所有的INNOBASE_SHARE。

  这里完成初始化一个innobase_share结构。


3. 加载数据字典:

  初始化innodb_share中的dict_table_t

步骤:
  mutex_enter(&(dict_sys->mutex));
    dict_sys_t:整个系统的数据字典, 全局的 dict_sys_t* dict_sys;
      包括:hash_table_t* table_hash; /*!< hash table of the tables, based
      包括:UT_LIST_BASE_NODE_T(dict_table_t) table_LRU; /*!< LRU list of tables */

  dict_table_get
  dict_table_get_low
    存在: dict_table_check_if_in_cache_low: 从hash表中取出,并更新lru链表。
    不存在:dict_load_table

1. load 表定义
2. load columns
3. load index
4. load foreign key

注:数组字典使用了两个结构存储,一个hash方便查询, 一个是lru链表,用于缓存的置换。

 

flush tables;


reload_acl_and_cache:
  1. 清空query_cache:使用structure_guard_mutex锁。
  2. close_cached_tables:关闭没有使用的。使用LOCK_open锁进行保护。  
  3. 递增:refresh_version

   free_cache_entry: free掉 table_cache中的table
    inter_close_table: 清空 io_cache
    closefrm:

  1. 关闭handler
  2. free innobase_share
  3. 释放table_share: 从table_def_cache上删除。

记录binlog:

  flush talbes记录了statement的binlog。

 

注: 如果使用了flush tables with read lock:将使用global的read lock, 通过meta lock来实现。

 

结论:
  对于一个表, flush_tables一共关闭了 table, table_share, handler, innobase_share. 只保留了dict_table_t数据字典。
  flush tables不关闭正在使用的,当table再次使用的时候,发现version已经发生了变化,就关闭,并重新打开。