Documentation Home
MySQL 8.3 Reference Manual
Related Documentation Download this Manual
PDF (US Ltr) - 40.8Mb
PDF (A4) - 40.9Mb
Man Pages (TGZ) - 294.0Kb
Man Pages (Zip) - 409.0Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb
Excerpts from this Manual

MySQL 8.3 Reference Manual  /  ...  /  How MySQL Opens and Closes Tables

10.4.3.1 MySQL 如何打开和关闭表

当您执行 mysqladmin 状态 命令时,您应该看到类似以下内容:

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

“Open tables” 值为 12 可能会让您感到困惑,如果您只有少于 12 个表。

MySQL 是多线程的,因此可能有多个客户端同时对同一个表执行查询。为了减少多个客户端会话对同一个表的状态不同的问题,每个并发会话独立打开表。这使用了更多的内存,但通常可以提高性能。对于 MyISAM 表,每个客户端需要一个额外的文件描述符来打开数据文件。(相比之下,索引文件描述符在所有会话之间共享。)

系统变量 table_open_cachemax_connections 影响服务器保持打开的文件数量的最大值。如果您增加这两个值之一,您可能会遇到操作系统对每个进程打开文件描述符的限制。大多数操作系统允许您增加这个限制,虽然方法因系统而异。请查看操作系统文档以确定是否可以增加限制和如何进行。

table_open_cachemax_connections 相关。例如,对于 200 个并发运行的连接,指定表缓存大小至少为 200 * N,其中 N 是任何查询中的最大表数目。您还需要为临时表和文件保留一些额外的文件描述符。

确保您的操作系统可以处理 table_open_cache 设置所隐含的打开文件描述符数量。如果 table_open_cache 设置太高,MySQL 可能会耗尽文件描述符并出现症状,如拒绝连接或无法执行查询。

还要注意 MyISAM 存储引擎需要每个唯一打开表的两个文件描述符。要增加 MySQL 可用的文件描述符数量,请设置 open_files_limit 系统变量。请参阅 第 B.3.2.16 节,“文件未找到和类似错误”

打开表的缓存保持在 table_open_cache 条目级别。服务器在启动时自动调整缓存大小。要明确设置缓存大小,请在启动时设置 table_open_cache 系统变量。MySQL 可能会临时打开更多表以执行查询,如本节后面所述。

MySQL 在以下情况下关闭未使用的表并将其从表缓存中删除:

当表缓存填满时,服务器使用以下过程来定位要使用的缓存条目:

  • 释放不再使用的表,开始从最少使用的表。

  • 如果需要打开新的表,但缓存已满且没有表可以释放,缓存将临时扩展以满足需求。当缓存处于临时扩展状态且某个表从使用状态变为未使用状态时,该表将被关闭并从缓存中释放。

每个并发访问都将打开一个 MyISAM 表。这意味着,如果两个线程访问同一个表,或者如果一个线程在同一个查询中访问同一个表两次(例如,通过将表连接到自己),那么该表需要打开两次。每个并发打开都需要在表缓存中占用一个条目。任何 MyISAM 表的第一次打开都需要两个文件描述符:一个用于数据文件,一个用于索引文件。每个附加的表使用只需要一个文件描述符用于数据文件。索引文件描述符在所有线程之间共享。

如果您使用 HANDLER tbl_name OPEN 语句打开一个表,对于该线程将分配一个专用的表对象。该表对象不会被其他线程共享,直到线程调用 HANDLER tbl_name CLOSE 或线程终止。当这种情况发生时,表将被放回表缓存中(如果缓存不满)。参见 第 15.2.5 节,“HANDLER 语句”

要确定您的表缓存是否太小,可以检查 Opened_tables 状态变量,该变量表示服务器启动以来表打开操作的次数:

mysql> SHOW GLOBAL STATUS LIKE 'Opened_tables';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Opened_tables | 2741  |
+---------------+-------+

如果该值非常大或快速增加,即使您没有发出许多 FLUSH TABLES 语句,增加 table_open_cache 值在服务器启动时。