当我们在执行mysqladmin status 命令或连接通过mysql客户端连接到实例后,执行\s的时候,应该看到类似以下的内容:
Uptime: 62239177 Threads: 132 Questions: 2739091116 Slow queries: 19983986 Opens: 2732 Flush tables: 1 Open tables: 2048 Queries per second avg: 44.009
今天我们就重点来看一下,Open tables和 Flush tables
MySQL是多线程的,因此可能有许多客户端同时为给定表发出查询。为了最大程度地减少同一张表上具有不同状态的多个客户端会话的问题,每个并发会话会独立打开该表。这会使用额外的内存,但通常会提高性能。对于MyISAM表,每个打开表的客户端的数据文件都需要一个额外的文件描述符。(相比之下,索引文件描述符在所有会话之间共享。)
该table_open_cache和 max_connections系统变量影响服务器保持打开的文件的最大数量。如果增加这两个值中的一个或两个,则可能会遇到操作系统对打开文件描述符的每个进程数的限制。
table_open_cache与相关max_connections。例如,对于200个并发运行的连接,指定的表缓存大小至少为 200 *N,其中 N是您执行的任何查询中每个联接的最大表数。还必须为临时表和文件保留一些额外的文件描述符。
确保操作系统可以处理该table_open_cache设置所隐含的打开文件描述符的数量 。如果 table_open_cache设置得太高,MySQL可能会用完文件描述符,并表现出诸如拒绝连接或无法执行查询之类的症状。
还应考虑到MyISAM 存储引擎对于每个唯一的打开表都需要两个文件描述符。要增加可用于MySQL的文件描述符的数量,请设置 open_files_limit系统变量。
打开表的缓存保持在table_open_cache条目级别 。服务器在启动时自动调整缓存大小。要显式设置大小,请在启动时设置table_open_cache 系统变量。MySQL可能会临时打开更多表来执行查询
在以下情况下,MySQL关闭未使用的表并将其从表缓存中删除:
当缓存已满并且线程尝试打开不在缓存中的表时。
当高速缓存包含多个table_open_cache条目并且高速缓存中 的表不再被任何线程使用时。
当进行表刷新操作时。当有人发出一条FLUSH TABLES语句或执行 mysqladmin flush-tables或 mysqladmin refresh命令时,会发生这种情况。
表高速缓存填满后,服务器将使用以下过程找到要使用的高速缓存条目:
从最近最少使用的表开始,释放当前未使用的表。
如果必须打开一个新表,但是缓存已满,并且无法释放任何表,则可以根据需要临时扩展缓存。当缓存处于临时扩展状态并且表从已使用状态变为未使用状态时,该表将关闭并从缓存中释放。
MyISAM将为每个并发访问打开 一个表。这意味着,如果两个线程访问同一个表,或者如果一个线程在同一查询中两次访问该表(例如,通过将表连接到自身),则该表需要打开两次。每个并发打开都需要在表缓存中有一个条目。任何MyISAM表的第一次打开都 需要两个文件描述符:一个用于数据文件,一个用于索引文件。该表的每次其他使用都只为数据文件使用一个文件描述符。索引文件描述符在所有线程之间共享。
如果要使用 HANDLER tbl_name 该语句打开表,则会为该线程分配专用的表对象。该表对象不与其他线程共享,并且在线程调用或线程终止之前不会关闭。发生这种情况时,会将表放回表高速缓存中(如果高速缓存未满)。
要确定表缓存是否太小,请检查 Opened_tables状态变量,该变量指示自服务器启动以来表打开操作的数量:
mysql> SHOW GLOBAL STATUS LIKE 'Opened_tables'; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | Opened_tables | 2741 | +---------------+-------+
如果该值很大或迅速增加,即使没有发出很多FLUSH TABLES语句,也请在服务器启动时增加table_open_cache该值。