MySQL 优化之 table_open_cache
背景:
MySQL实例利用率一直居高不下
问题排查:
1. 查看连接数,没发现有长时间未释放的长链接
mysql> show full processlist;
2、查看表高速缓存设置
mysql> show variables like '%table_open_cache%';
3、查看实际缓存状态
mysql> show global status like 'open%tables%'; +---------------+--------+ | Variable_name | Value | +---------------+--------+ | Open_tables | 785 | | Opened_tables | 508331 | +---------------+--------+
table_open_cache 与 Open_tables 值相等,但是Opend_tables值很大。说明MySQL正在释放缓存的表以容纳新的表,这个过程消耗资源。所以需要加大 table_open_cache的值,我们的MySQL实例是4G内存,这里我们改成2048。
4、变更设置
临时修改:
mysql> set global table_open_cache = 2048;
配置文件修改:
[mysqld] table_open_cache = 2048
5、table_open_cache合理值的建议
Open_tables / Opened_tables >= 0.85 表的重复使用率
Open_tables / table_open_cache <= 0.95 缓存里存在的已打开的表
实际操作过程中,可以把table_open_cache值设置得比Open_tables大一些,然后慢慢增加,逐步调试。
调大 table_open_cache 参数值,减少业务表频繁打开和关闭。至于调整到多少合适,查看 MySQL 状态参数 Open_tables 和 Opened_tables,当 Open_tables 接近 table_open_cache,并且 Opened_tables 不会快速增加时,那么此时的 table_open_cache 值就是一个比较合适的值。
table_open_cache 也不是越大越好,毕竟在表多的时候,也需要更多的内存消耗。
除了 table_open_cache 之外,还有两个参数,可以一起关注一下:
- table_open_cache_instances
- table_definition_cache
如果 table_open_cache_instances 设置过小,在高并发场景下,可能导致 MySQL 内部线程严重的mutex 竞争