暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

mysql表对象缓存

老子瞎说 2019-07-12
564

    

    表对象缓存就是将表的字典信息缓存到内存中,用来提高对表的访问效率。某个表被访问后,在服务器没有关闭且表定义没有被修改的条件下,访问这个表时,只需从内存中找到这个缓存的表对象即可,而不必再次从系统表中读取它的定义解析。也说明,在某个表需要更改表结构时,这个表不能被其它用户打开,否则会产生MDL(元数据锁),错误表现是:waiting for table metadata lock.


    mysql的表对象缓存比较特别,因为是插件式多存储引擎的,这样它的表对象缓存也就出现了两层,类似于开发语言中的类和对象的关系。(有开发基础的同学可能会更好的理解类和对象)

拿mysql两种常见的存储引擎:myisam  innodb举例

myisam表文件:.frm  .MYD  .MYI ;

innodb表文件:  .frm   .ibd ;

    因为mysql不同种类的表都有.frm表结构文件,这也是表缓存第一层需要读取的文件。

    第一层缓存,也是静态缓存或称为共享(share)缓存,这相当于给表定义了一个结构类:

    表对象缓存是把表结构缓存到内存中,也就是.frm文件,这个不分引擎表,都是有的。

    表对象缓存的存储形式是以hash键值对存放在table_define_chche内存中的。

    第二层缓存,也称动态缓存,是对表使用过程中的实例化。

    对于同一个静态表缓存,每一次实例化都相当于打开一张表,会将这些信息存放到open_tables_cache中。可以直接通过命令:show open tables where in_use>0;查看当前已经打开的表。当一个操作完成后,它所实例化的表就不需要了,此时系统不是将这个本地的实例直接释放,而是将其保存下来,为了下次某个用户再次访问这个表是不需要重新实例化,当然会调用ha_reset将这个实例状态恢复。这也是为什么show open tables 会有大量的in_use=0的表。这些表有实例化,但是没有被使用。


    现在可以知道,mysql中表对象的缓存其实是两部分,一部分是share的缓存,也就是多个不同表的share的缓存;另一部分是每个share结构被实例化后的实例对象的缓存,mysql用来管理缓存空间大小的方法是通过计数实现的。默认情况下,系统中总的share个数不超过table_definition_cache个。总共打开的表个数不超过table_open_cache个。

优缺点

1.share缓存在使用时才读到内存中,相对去reload形式的全字典缓存,效率会查一下,但节省内存空间。

2.share缓存、table缓存 是以记个数的方式来控制的,这样没法准确控制内存的使用量。可能存在缓存个数已达上限,但内存剩余量还很大,或内存已达上限但缓存个数却很少。

    其实mysql的表对象缓存内容很多,设计到源码的东西就不太容易理解了。我也是捋了一层最上面的东西,方便理解。


    抛砖引玉,写的不对的地方尽情pen pen ~~





文章转载自老子瞎说,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论