Chinaunix首页 | 论坛 | 博客
  • 博客访问: 153620
  • 博文数量: 12
  • 博客积分: 226
  • 博客等级: 二等列兵
  • 技术积分: 221
  • 用 户 组: 普通用户
  • 注册时间: 2012-11-10 23:15
文章分类

全部博文(12)

分类: Mysql/postgreSQL

2012-11-16 13:24:08

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进行维护

点击(此处)折叠或打开

  1. mysql_execute_command
  2. ...................
  3. |->open_tables
  4.   |->open_table
  5. ...................
  6. ...execute query...
  7. ...................
  8. |->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,调用流程如下:

点击(此处)折叠或打开

  1. hash_delete(&open_cache,(uchar*) unused_tables)
  2. free_cache_entry
  3. |->intern_close_table
  4.   |->closefrm
  5.     |->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,调用流程如下:

点击(此处)折叠或打开

  1. my_hash_delete(&table_def_cache, (uchar*) oldest_unused_share);
  2. table_def_free_entry
  3. |->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使用的表放回空闲链表中,代码调用:

点击(此处)折叠或打开

  1. mysql_execute_command
  2. |->close_thread_tables
  3.   |->close_open_tables
  4.     |->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结构体中的几个变量:

点击(此处)折叠或打开

  1. struct TABLE_SHARE
  2. {
  3.   ...
  4.   TABLE_SHARE *next, **prev; /* Link to unused shares */
  5.   /* prev为二级指针,保存的是指向自己的指针(前一个节点的next指针)的地址 */
  6.   /*
  7.     Doubly-linked (back-linked) lists of used and unused TABLE objects
  8.     for this share.
  9.   */
  10.   I_P_List <TABLE, TABLE_share> used_tables;
  11.   I_P_List <TABLE, TABLE_share> free_tables;
  12.   ...
  13. }

本质上,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运行时的并发数有关,如果系统并发连接比较多应当适当设置大些

阅读(4958) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~