当前位置: 首页 > 数据库 > 正文

MySQL 的 open_files_limit,table_open_cache和max_connections

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);

下面的比较有趣:

  • 在设置setrlimit 之前,mysql获取当前的limit值,如果当前的 limit 是 unlimited,它将尝试设置比之前获得的limit值更小。
  • 如果当前limit不是 unlimited 并且高于获取的limit,直接返回。
  • 如果上面的两种条件都不满足,即当前设置了limit,非unlimited,但是小于之前获取的limit值,它将使用这个值设置setrlimit:(1)如果失败,返回之前得到的 getrlimit 值,(2)如果成功,将再次获取getrlimit值,并返回结果。
  • 如果收到的limit小于它所需要的,plimit < wanted_files: 如果open_files_limit 没有设置,将基于获取的plimit重新调整max_connections 和 table_cache_size。
    /*
              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中配置的不一样。

    这对我们有什么指示呢?

  • mysql仅仅可以改变OS层面指定的soft limit,如果触及到了hard limit,将会走上面的流程(因为非root用户,无法自己增加)可以通过ulimit -H 和 ulimit -S 检查当前用户下的值,可用在/etc/security下面进行设置。
  • 如果设置了(max_connections,table_open_cache全部或者之一)和open_files_limit,应为操作系统的限制mysql将不能获得期望的limit值,mysql连接将会出现意外的失败并且可能导致文件描述符被耗尽(在max_connections或者有很多大表的情况下)

  • 一个好的做法是不设置open_files_limit,仅仅使用全局的limit设置,MYSQL本身已经足够智能,可以计算出它实际的需要进行配置。对于全局的limits,可以设置一个limit值之上正常的值,根据应用的实际需要配置max_connections/table_cache变量。
  • 使用之前获取的值的一个负面作用是如果高于操作系统的限制,max_connections 和 table_cache会被做相应的调整。

  • 你可以设置open_files_limit到UINT_MAX(假设操作系统允许),MYSQL文档中提到(平台依赖),对于64位操作系统,可以设置到最大400w。
  • 很明显,如果你仅仅设置了open_files_limit,但是没有max_connections 或者 table_open_cach,mysql将不会调整他们去匹配open_files_limit。

  • 一些情况下你会想设置open_files_limit,对于实例来讲,他们使用这些变量去设置自己的limits,并没有基于max_connections 和 table_cache
  • 如果你要在与运行mysql的共享服务器(同时运行了apache等)上设置这些变量,你要特别注意系统一些error log。

  • max_connections 和 table_open_cache 是动态的变量,而open_files_limt不是。你可以在系统运行是修改max_connections的值,但并不是所有的变量都可以动态修改。
  • 根据之前的理解,在配置open_files_limit你应该预留一些buffer,给mysql自己留一些遐想的空间,也给未来使用预留一定的空间。

  • 在使用 MariaDB 和 Percona Server的情况下,由于线程池的需要,额外需要配置extra_max_connections参数。

    原文wnohang.net

    本文固定链接: https://sudops.com/mysql-open-file-limit-max_connections-table-open-cache.html | 运维速度

  • 该日志由 u2 于2014年05月12日发表在 数据库 分类下,
    原创文章转载请注明: MySQL 的 open_files_limit,table_open_cache和max_connections | 运维速度
    关键字:

    报歉!评论已关闭.