MySQL的变量open_files_limit,table_open_cache和max_connections是相互关联的。如果对有些变量进行了设置,有的变量没有设置,mysql会根据一定的计算公式进行计算得出其他的,当然有些时候会触发mysql的一些警告来。具体的计算流程及如何得出最终的文件描述符有些许复杂,下面将简单阐述一下(均基于Linux系统)
首先,mysql会基于 max_connections 和 table_open_cache 的值计算最低需要的文件打开描述符的数量。至于其他变量,如果没有再my.cnf中配置或者命令行中指定,它将使用默认值。
/* MyISAM requires two file handles per table. */ wanted_files= 10+max_connections+table_cache_size*2;
其次,它会基于 open_files_limit 检查实际能分配多少数值。这里它可分配的最大数值为 max_connections 5倍,然后三者取最大值。
max_open_files= max(max(wanted_files, max_connections*5),open_files_limit); files= my_set_max_open_files(max_open_files);
接下来,它获取 max_open_files 和服务器(操作系统/平台)支持的最大描述符限制数的最低值
limit = min(max_file_limit, OS_FILE_LIMIT);
下面的比较有趣:
/* If we have requested too much file handles than we bring max_connections in supported bounds. */ max_connections= (ulong) min(files-10-TABLE_OPEN_CACHE_MIN*2, max_connections); /* Decrease table_cache_size according to max_connections, but not below TABLE_OPEN_CACHE_MIN. Outer min() ensures that we never increase table_cache_size automatically (that could happen if max_connections is decreased above). */ table_cache_size= (ulong) min(max((files-10-max_connections)/2, TABLE_OPEN_CACHE_MIN), table_cache_size); DBUG_PRINT(“warning”, (“Changed limits: max_open_files: %u max_connections: %ld table_cache: %ld”, files, max_connections, table_cache_size)); if (global_system_variables.log_warnings)
上面这个计算公式说明: TABLE_OPEN_CACHE_MIN 为 400
如果 open_files_limit limit已经设置,将会打印我们熟悉的警告:“Could not increase number of max_open_files to more”.
最后,它把变量open_files_limit 设置为plimit,这就是为什么你经常能看到实际运行中open_files_limit跟你在my.cnf中配置的不一样。
这对我们有什么指示呢?
如果设置了(max_connections,table_open_cache全部或者之一)和open_files_limit,应为操作系统的限制mysql将不能获得期望的limit值,mysql连接将会出现意外的失败并且可能导致文件描述符被耗尽(在max_connections或者有很多大表的情况下)
使用之前获取的值的一个负面作用是如果高于操作系统的限制,max_connections 和 table_cache会被做相应的调整。
很明显,如果你仅仅设置了open_files_limit,但是没有max_connections 或者 table_open_cach,mysql将不会调整他们去匹配open_files_limit。
如果你要在与运行mysql的共享服务器(同时运行了apache等)上设置这些变量,你要特别注意系统一些error log。
根据之前的理解,在配置open_files_limit你应该预留一些buffer,给mysql自己留一些遐想的空间,也给未来使用预留一定的空间。