table_open_cache 与 table_definition_cache 对MySQL(内存)的影响
1. 现象,内存使用大 首先说一下最近遇到的一个现象,因为分库的缘故,单实例里面的表的数量增加了20倍,总数将近达到10000个。在开发环境明显感觉到执行简单查询都很慢,在processlist里面看到状态 opening table 达到好几秒但数据库并没有什么负载。本能的想到应该要加大 table_open_cache,可是加大后发现MySQL刚启动 RES 就占用了2.5G内存,之前才500-600M的样子。 只是将 table_open_cache 从默认的2000,增加到10000(先不论这个值合不合理),就独占了2G的内存,这对于生产环境内存浪费是不可接受的。还好,关于这个问题的讨论有不少,感兴趣的话可以阅读 #bug 68287, #bug 68514, 12015-percona-5-6-14-56-very-high-memory-usage。 Oracle官方工程师并不认为这是个bug,导致初始化分配这么多内存的原因是,开启了 Performance_Schema 。P_S测量数据库的性能指标,需要提前一次性分配内存,而不是随着数据库运行逐渐申请内存。 下表是不同参数组合下内存占用的测试结果: (注:可以通过这个来查看PFS里面哪些占内存比较多,mysql -hxxxx -Pxxx -uxx -pxx -e "show engine performance_schema status"|grep memory|sort -nr -k3 |head ) 对于 table_open_cache 设置的非常大的情况下,即使还有许多cache多余,但P_S都需要分配这个数量的内存。解决这个内存大的问题有3个方向: table_open_cache, table_definition_cache, max_connections 设置合理 关闭 performance_schema 保持 PFS 开启,关闭测量 max_table_instances和max_table_handles performance_schema_max_table_instances: 最大测量多少个表对象 对应 (pfs_table_share).memory,我的环境里固定 277600000 bytes performance_schema_max_table_handles: 最大打开表的总数 对应(pfs_table).memory,随着 table_open_cache 的增大而增大 关闭的方法是在my.cnf里面设置以上变量为 0 。默认是 -1 ,表示 autosize,即根据 table_open_cache/table_def_cache/max_connections 的值自动设置,相关代码 pfs_autosize.cc: PFS_sizing_data *estimate_hints(PFS_global_param *param) { if ((param->m_hints....