总结一下:table_open_cache 代表 MySQL Server 所允许的所有线程打开表的总数量。这个变量可能会受 fd 文件描述符的影响。因此要经过测试慎重使用。
classTable__cache 缓存设计机制
MySQL 是多线程的,可以使用所有可用的 CPU。这意味着不同的线程内的多个会话都有可能同时访问同一张表。而表数据最终还是磁盘上的数据文件。
如果每次都去反复重复打开和关闭表的文件句柄,这也太费资源了。肯定会影响使用性能。
因此 MySQL 官方设计了这个与 table_open_cache 相关的机制,在源码文档
classTable__cache
中进行了缘由介绍:
The idea behind this cache is that most statements don't need to go to a central table definition cache to get a TABLE object and therefore don't need to lock LOCK_open mutex. Instead they only need to go to one Table_cache instance (the specific instance is determined by thread id) and only lock the mutex protecting this cache. DDL statements that need to remove all TABLE objects from all caches need to lock mutexes for all Table_cache instances, but they are rare.
该机制简单来讲就是:“
MySQL 通过线程获取本地 Table_cache 的缓存实例,减少对全局 LOCK_open 锁的竞争,从而优化并发查询性能
。DDL 操作需全局加锁但较为罕见。”
具体场景描述
接下来结合 MySQL Table_cache 的缓存命中流程来讲解一下步骤。这样好理解一些。
关键步骤如下:
MySQL Server 查询执行时,线程首先检查当前线程本地的 Table_cache 实例是否已经缓存了所需表的句柄。