mysql / 5.7 / reference / table-cache.html

8.4.3.1 MySQL 如何打开和关闭 table

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

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

如果 table 少于 12 个,则Open tables的值 12 可能会令人困惑。

MySQL 是多线程的,因此可能有许多 Client 端同时为给定 table 发出查询。为了最大程度地减少同一张 table 上具有不同状态的多个 Client 端会话的问题,每个并发会话会独立打开该 table。这将使用额外的内存,但通常可以提高性能。对于MyISAMtable,每个打开 table 的 Client 端的数据文件都需要一个额外的文件 Descriptors。 (相比之下,索引文件 Descriptors 在所有会话之间共享.)

table_open_cachemax_connections系统变量影响服务器保持打开状态的最大文件数。如果增加这两个值中的一个或两个,则可能会遇到 os 对打开文件 Descriptors 的每个进程数施加的限制。许多方法允许您增加打开文件的限制,尽管方法因系统而异。请查阅您的 os 文档,以确定是否可以增加限制以及如何增加限制。

table_open_cachemax_connections相关。例如,对于 200 个并发运行的连接,指定的 table 缓存大小至少为200 * N,其中* N *是您执行的任何查询中每个联接的最大 table 数。您还必须为临时 table 和文件保留一些额外的文件 Descriptors。

确保您的 os 可以处理table_open_cache设置所隐含的打开文件 Descriptors 的数量。如果table_open_cache设置得太高,MySQL 可能会用完文件 Descriptors,并 table 现出诸如拒绝连接或无法执行查询之类的症状。

还应考虑到MyISAM存储引擎为每个唯一的打开 table 都需要两个文件 Descriptors。对于MyISAM分区 table,打开的 table 的每个分区都需要两个文件 Descriptors。 (MyISAM打开分区 table 时,无论是否实际使用给定的分区,它都会打开该 table 的每个分区.请参见MyISAM 和分区文件 Descriptors 的用法。)要增加可用于 MySQL 的文件 Descriptors 的数量,请设置open_files_limit系统变量。参见B.4.2.17 节,“找不到文件和类似错误”

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

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

  • 当缓存已满并且线程尝试打开不在缓存中的 table 时。

  • 当高速缓存包含多个table_open_cache个条目并且高速缓存中的 table 不再被任何线程使用时。

  • 当进行 table 刷新操作时。当有人发出FLUSH TABLES语句或执行mysqladmin flush-tablesmysqladmin refresh命令时,就会发生这种情况。

当 table 高速缓存填满时,服务器将使用以下过程找到要使用的高速缓存条目:

  • 从最近最少使用的 table 开始,释放当前未使用的 table。

  • 如果必须打开一个新 table,但是缓存已满并且无法释放任何 table,则可以根据需要临时扩展缓存。当缓存处于临时扩展状态并且 table 从使用状态变为未使用状态时,table 将关闭并从缓存中释放。

将为每个并发访问打开一个MyISAMtable。这意味着,如果两个线程访问同一个 table,或者如果一个线程在同一查询中两次访问该 table(例如,通过将 table 连接到自身),则该 table 需要打开两次。每个并发打开都需要在 table 缓存中有一个条目。任何MyISAMtable 的第一次打开都需要两个文件 Descriptors:一个用于数据文件,一个用于索引文件。该 table 的每次其他使用都只为数据文件使用一个文件 Descriptors。索引文件 Descriptors 在所有线程之间共享。

如果要使用HANDLER tbl_name OPEN语句打开 table,则会为该线程分配专用的 table 对象。该 table 对象不与其他线程共享,并且在线程调用HANDLER tbl_name CLOSE或线程终止之前不会关闭。发生这种情况时,会将 table 放回 table 缓存中(如果缓存未满)。参见第 13.2.4 节“ HANDLER 语句”

要确定 table 缓存是否太小,请检查Opened_tables status 变量,该变量指示自服务器启动以来 table 打开操作的数量:

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

如果该值很大或迅速增加,即使您没有发出很多FLUSH TABLES语句,也要在服务器启动时增加table_open_cache值。