MySQL open_tables和opened_tables
官网解释参见:https://dev.mysql.com/doc/refman/5.7/en/table-cache.html
其他可供参考的文章有:
关于表限制参数的使用:https://dba.stackexchange.com/questions/5232/mysql-table-cache-and-opened-tables
关于SHOW OPEN TABLES命令的使用:https://www.percona.com/blog/2008/12/14/show-open-tables-what-is-in-your-table-cache/
一、本文涉及到的系统参数有3个:
这是个server层的参数,mysql不支持并行查询,mysql的会话也没有PGA的概念,一个thread引用myisam表时需要在server层上创建一个table对象(索引也需要创建一个但是是共享的,self join会创建2个,分区表每个分区按单表对待),如果同时多个会话引用一个表也会创建多个表对象,虽然会加大内存使用量,但是却极大的减少了内部表锁的争用。 这个值的数目建议设置为max_connections*你的表数目,当然你可能也需要为一些临时表等对象预留,但是这个数目已经足够大啦。 那么mysql什么时候释放这些表对象呢?
三、相关原理图
参考:http://www.cnblogs.com/xpchild/p/3780625.html的源码解析。
如下图,有个表叫xpchild(小屁孩666)库中的pp表:
table: MySQL会为一个join查询中涉及的每个表建一个TABLE对象,引用innodb表时还会创建innodb层的handler,server层的table指向此handler,此handler指向innodb层的共享表字典Dict_table_t。
table_share: MySQL为每一张表建立一个table_share对象,与frm文件对应。
handler: 在Innodb层对应于每个TABLE对象,innodb引擎创建一个handler(windows叫句柄,linux叫file descriptor)。
dict_table_t: innodb为每一个innodb表load一个数据字典对象,这些对象的集合就是innodb中的data dictionary。
你可以将table和handler看做非innodb和innodb在各个会话中被引用时创建的句柄,前者在server层,后者自然在innodb引擎层。 flush tables with read lock:close了server层创建的所有的table对象,并为所有table_share上加一个全局读锁,因此innodb层中指向table对象的handler也就无用了。
扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄
- table_open_cache
这是个server层的参数,mysql不支持并行查询,mysql的会话也没有PGA的概念,一个thread引用myisam表时需要在server层上创建一个table对象(索引也需要创建一个但是是共享的,self join会创建2个,分区表每个分区按单表对待),如果同时多个会话引用一个表也会创建多个表对象,虽然会加大内存使用量,但是却极大的减少了内部表锁的争用。 这个值的数目建议设置为max_connections*你的表数目,当然你可能也需要为一些临时表等对象预留,但是这个数目已经足够大啦。 那么mysql什么时候释放这些表对象呢?
- 当缓冲已满,而连接想要打开一个不在缓冲中的表时。
- 当缓冲数目已经超过了table_open_cache设置的值,mysql开始使用LRU算法释放表对象。
- 当你用flush tables;语句时。
- open_files_limit
- innodb_open_files



你可以将table和handler看做非innodb和innodb在各个会话中被引用时创建的句柄,前者在server层,后者自然在innodb引擎层。 flush tables with read lock:close了server层创建的所有的table对象,并为所有table_share上加一个全局读锁,因此innodb层中指向table对象的handler也就无用了。

更多精彩