mysql 5.1 table_cache_mysql table cache源码分析

mysql 5.1 table cache

table cache包含table open cache和table definition cache,都由server层管理

table_open_cache: 内存中缓存的打开的表的TABLE实例数目,线程之间独立,一个表可以被多个线程同时打开从而在table cache中可以有多个实例

table_definition_cache:内存中缓存打开的表的TABLE_SHARE实例数目,一个share在table cache中只有一个实例

mysql 5.1使用open_cache(HASH)管理table cache,每个TABLE实例中包含一个TABLE_SHARE指针成员s,它在不同的TABLE实例间共享,s内部有一个引用计数单元,记录了table cache中引用s的TABLE实例个数

当有引用s的TABLE实例被释放,其引用计数减1,如果s的引用计数减为0,且此时table_def_cache.records > table_def_size时,s也会被释放掉,TABLE_SHARE被table_def_cache(HASH)维护

5.1.25之后,table_definition_cache:默认和最小都是256

query/dml引起的table cache管理

free_cache_entry:从table cache中删除一个TABLE实例

table_def_free_entry:从table_def_cache中删除一个TABLE_SHARE实例

query/dml执行过程中调用open_tables,close_thread_tables等函数时会对table cache进行维护

点击(此处)折叠或打开

mysql_execute_command

...................

|->open_tables

|->open_table

...................

...execute query...

...................

|->close_thread_tables

何时释放TABLE?

1、close_cached_tables,如FLUSH TABLES

2、open_table,当需要新建一个TABLE实例,即未在table cache中找到空闲的TABLE,会做检查,当open_cache.records > table_cache_size时,unused_tables(TABLE链表)会被释放,直到open_cache.records <= table_cache_size,调用流程如下:

点击(此处)折叠或打开

hash_delete(&open_cache,(uchar*) unused_tables)

free_cache_entry

|->intern_close_table

|->closefrm

|->release_table_share

release_table_share中会对table_def_cache.records进行检查,如果其值超过table_def_size且其引用计数为0,table share也被释放

在closefrm中,TABLE实例中的handler指针file被释放,会调用一系列存储引擎的函数,相应的,在新分配一个TABLE实例时,会初始化file指针,调用get_new_handler,file->open等函数,这些操作有一定的代价,应该减少

释放的TABLE是位于unused_tables中,否则table cache将自动扩展,暂时不释放

何时释放TABLE_SHARE?

1、get_table_share(在open_table中被open_unireg_entry调用),会进行检查,当table_def_cache.records > table_def_size时,oldest_unused_shares(TABLE_SHARE链表)会被释放,直到table_def_cache.records <= table_def_size,调用流程如下:

点击(此处)折叠或打开

my_hash_delete(&table_def_cache, (uchar*) oldest_unused_share);

table_def_free_entry

|->free_table_share

2、close_cached_tables,如执行FLUSH TABLES

3、释放TABLE时,引用计数减为0且table_def_cache大小超过table_def_size

释放TABLE_SHARE时,其ref_count为0,如果ref_count不为0,table_def_cache被扩展,在以后当ref_count为0时被释放

table cache LRU 管理

当一个query/dml结束后,会将thd使用的表放回空闲链表中,代码调用:

点击(此处)折叠或打开

mysql_execute_command

|->close_thread_tables

|->close_open_tables

|->close_thread_table

TABLE_SHARE的释放采用LRU顺序,由oldest_unused_share,end_of_unused_share这两个链表指针控制实现:空闲的SHARE是插入到end_of_unused_share之前,即尾插法,而释放时是从链表的头部oldest_unused_share开始的,代码详见release_table_share和table_def_init函数

空闲TABLE实例的释放也采用LRU顺序,TABLE空闲时被移到unused_tables中是插在链表的尾部,释放时也是从unused_tales头部开始,整个unused_tables是一个环形的双链表,代码详见close_thread_table和free_cache_entry函数

mysql 5.5 table cache

table_definition_cache:默认和最小都是400

5.1中table cache的open_cache(HASH)已经不使用了,而是在TABLE_SHARE中增加了两个链表used_tables和free_tables,用以管理该表上打开的TABLE实例

TABLE_SHARE结构体中的几个变量:

点击(此处)折叠或打开

struct TABLE_SHARE

{

...

TABLE_SHARE *next, **prev; /* Link to unused shares */

/* prev为二级指针,保存的是指向自己的指针(前一个节点的next指针)的地址 */

/*

Doubly-linked (back-linked) lists of used and unused TABLE objects

for this share.

*/

I_P_List

I_P_List

...

}

本质上,5.1和5.5在table cache的管理上没有很大区别,搜索的效率是一样的,5.5通过table_def_cache先找到TABLE_SHARE,后在free_tables链表中找空闲的TABLE,而5.1直接在open_cache中搜索没有被使用的TABLE。

对于table_def_cache,只要设置不低于数据库中表的个数就行了,而对于table_open_cache和MySQL运行时的并发数有关,如果系统并发连接比较多应当适当设置大些

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值