第7章:优化 / 7.4. 优化数据库结构 / 7.4.9. MySQL如何打开和关闭表

table_cachemax_connectionsmax_tmp_tables系统变量影响服务器保持打开的文件的最大数量。如果你增加这些值其中的一个或两个,会遇到操作系统为每个进程打开文件描述符的数量强加的限制。许多操作系统允许你增加打开的文件的限制,尽管该方法随系统的不同而不同。查阅操作系统文档以确定是否可以增加限制以及如何操作。

table_cachemax_connections有关。例如,对于200个并行运行的连接,应该让表的缓存至少有200 * N,这里N是可以执行的查询的一个联接中表的最大数量。还需要为临时表和文件保留一些额外的文件描述符。

确保操作系统可以处理table_cache设置所指的打开的文件描述符的数目。如果table_cacheis设得太高,MySQL可能为文件描述符耗尽资源并拒绝连接,不能执行查询,并且很不可靠。还必须考虑到MyISAM存储引擎需要为每个打开的表提供两个文件描述符。可以在mysqld_safe中使用--open-files-limit启动选项来增加MySQL适用的文件描述符的数量。参见A.2.17节,“文件未找到”

打开表的缓存可以保持在table_cache条。 默认为64;可以用mysqld--table_cache选项来更改。请注意 MySQL可以临时打开更多的 表以执行查询。

在下面的条件下,未使用的表将被关闭并从表缓存中移出:

·         当缓存满了并且一个线程试图打开一个不在缓存中的表时。

·         当缓存包含超过table_cache个条目,并且缓存中的表不再被任何线程使用。

·         当表刷新操作发生。当执行FLUSH TABLES语句或执行mysqladmin flush-tablesmysqladmin refresh命令时会发生。

当表缓存满时,服务器使用下列过程找到一个缓存入口来使用:

·         当前未使用的表被释放,以最近最少使用顺序。

·         如果缓存满了并且没有表可以释放,但是一个新表需要打开,缓存必须临时被扩大。

如果缓存处于一个临时扩大状态并且一个表从在用变为不在用状态,它被关闭并从缓存中释放。

对每个并发访问打开一个表。这意味着,如果2个线程访问同一个表或在同一个查询中访问表两次(例如,将表连接为自身时),表需要被打开两次。每个并行的打开要求在表缓存中有一个条目。任何表的第一次打开占2个文件描述符:一个用于数据文件另一个用于索引文件。表的每一次额外使用仅占一个数据文件的文件描述符。索引文件描述符在所有线程之间共享。

如果你正用HANDLER tbl_name OPEN语句打开一个表,将为该线程专门分配一个表。该表不被其它线程共享,只有线程调用HANDLER tbl_name CLOSE或线程终止后才被关闭。表关闭后,被拉回表缓存中(如果缓存不满)。参见13.2.3节,“HANDLER语法”

可以通过检查mysqld的状态变量Opened_tables确定表缓存是否太小:

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

如果值很大,即使你没有发出许多FLUSH TABLES语句,也应增加表缓存的大小。参见5.3.3节,“服务器系统变量”5.3.4节,“服务器状态变量”