跳转至

MySQL是如何打开和关闭表?

当执行mysqladmin status命令时,应该看到类似以下的内容:

Uptime: 426 Running threads: 1 Questions: 11082
Reloads: 1 Open tables: 12

MySQL是多线程的,因此可能有许多客户端同时对一个给定表发出查询。为了最大程度地减少同一张表上具有不同状态的多个客户端会话的问题,每个并发会话会独立打开该表。这会额外消耗更高内存,但通常会提高性能。

https://dev.mysql.com/doc/refman/8.4/en/table-cache.html

MySQL通过**TABLE对象**进行表的读写等操作,对于构建TABLE对象所需的表定义相关信息,MySQL会通过Dictionary_client与DD模块进行交互。

在打开一个表准备访问数据的时候,通常要先打开其数据字典,其中包含了字段信息,索引信息,默认值,字符集,统计数据,自增字段,自增锁等等信息。

其中有些在MySQL层,有些在Innodb层(比如统计信息),又比如字段类型在MySQL层和Innodb层的表示是不同的,实际上这包含3层信息:

  • table instance:MySQL层相关的字典信息,每个会话独占由table share生成而来。在语句结束的时候释放,这里的释放并不是真正的释放,可能是缓存,其缓存的个数和table_open_cache和table_open_cache_instances有关,其缓存位置约定为table cache,内部为TABLE。

  • table share:MySQL层相关字典的信息,整个数据库只有一份,每个表都包含一个。5.7来自FRM文件,8.0则来自新的SDI缓存相关字典信息。当没有table cache引用的时候会考虑释放,但是同前面一样,释放可能是缓存,缓存的个数和table_definition_cache有关,其缓存位置约定为table def cache,内部为TABLE_SHARED。

  • dict table:Innodb层的信息,这个数据库只有一份,每个表都包含一个,其信息来自Innodb的数据字典,主要是SYS_TABLES/SYS_COLUMN等几个表。当没有table cache引用的时候会考虑释放,同样释放可能是缓存,缓存的个数依旧和table_definition_cache有关,其缓存位置约定为dict table cache,内部为dict_table_t