技术社群的这篇文章《第12问:Table cache 有什么作用?》讲解了和table cache知识相关的实验,学习了解下。
相关历史文章,《小白学习MySQL - table_open_cache的作用》。
问题
我们都知道 MySQL 的 Table Cache 是表定义的缓存,江湖上流传着各种对这个参数的调优方法。我们通过实验来验证 Table Cache 的作用。
实验
我们先创建一个测试数据库,
建一张空表,
建立一个连接,检查一下会话的初始状态,
在另一个窗口,开启 strace 追踪 MySQL 服务器的文件操作,
在 MySQL 中 select 新创建的表,
检查状态,
看到该操作没命中 table cache。
查看 strace,确实发现 mysqld 进程打开了表结构文件(test_tbl.frm),如果我们在 strace 中也抓获 read 事件(参数改为 "-e file,read"),那可以看到 mysqld 确实读取了表结构文件。
我们再次在该会话中进行 select,
可以看到开始命中 table cache 了。在 strace 的输出中,也没有抓到新的文件操作。
可以看出 table cache 的作用,就是节约读取表结构文件的开销。
那不命中 table cache,一定会有读取表结构文件的开销么?
我们开一个新的会话,这里增加了一个标识来区分会话,
在新会话中进行 select,查看状态,
看起来确实 table cache 没有命中,也就是说 table cache 是针对于线程的,每个线程有自己的缓存,只缓存本线程的表结构定义。
不过我们发现,strace 中没有关于表结构文件的 open 操作(只有 stat 操作,定位表结构文件是否存在),也就是说 table cache 不命中,不一定需要读取表结构文件。
这种感觉好像是:在不命中 table cache 时,命中了另外一个表结构缓存。这个缓存就是之后我们会介绍的 table_definition_cache。
💡运维建议:
我们读一下 MySQL 的文档,关于 table_open_cache 的建议值公式:
建议值 = 最大并发数 * join 语句涉及的表的最大个数。
通过实验我们容易理解:table_cache 是针对于线程的,所以需要最大并发数个缓存。
另外,一个语句 join 涉及的表,需要同时在缓存中存在。所以最小的缓存大小,等于语句 join 涉及的表的最大个数。
将这两个数相乘,就得到了 MySQL 的建议值公式。
如果您认为这篇文章有些帮助,还请不吝点下文章末尾的"点赞"