zoukankan      html  css  js  c++  java
  • mysql open files

    错误信息如下:

    .....
    150905 13:10:17 [ERROR] /usr/local/mysql/bin/mysqld: Can't open file: './mytest/t1.frm' (errno: 24)
    150905 13:10:17 [ERROR] /usr/local/mysql/bin/mysqld: Can't open file: './mytest/t2.frm' (errno: 24)
    ......
    150905 13:10:17 [ERROR] Error in accept: Too many open files
    ....
    

    注意到, 系统错误代号是 24, 用 perror 来查看一下具体的错误信息是什么:

    [root@myplace]# /usr/local/mysql/bin/perror 24
    OS error code  24:  Too many open files
    

    原来是打开文件太多了, 好办.用sysctl来调整一下就好了:

    [root@myplace]# sysctl -w fs.file-max=43621
    [root@mypalce]# sysctl -a | grep fs.file-max
    fs.file-max = 43621
    

    最后, 还有最重要的一点是, 修改 mysqld 的配置文件 my.cnf, 增加如下一行:

    open_files_limit = 4096 
    #根据自己的情况适当调整,系统默认值是 
    # max_connections*5 或 max_connections + table_cache*2
    

    然后, 以root身份重新启动 mysqld. 在这里, 尽管 my.cnf 中指定的运行用户不是root, 一样可以以root身份来启动mysqld, 否则 open_files_limit 选项无法生效, 因为内核限制了普通用户的最多打开文件数.

    目前open file超过limit的问题:

    除了socket,binlog, relay log, ibdata, logfile等这些固定需要打开的句柄以外,

    剩下的各种存储引擎的数据文件的打开数量,只应该和即时的IO并发请求量有关系,和用户的请求, 压力, 多少张表没有什么关系。

    所以,出现的open file太多的问题,属于代码缺陷, 目前集中在Myisam和tukodb引擎:

    InnoDB引擎严格按照Innodb_open_files的设置,使用LRU管理open file,不会遇到这个问题。 

    flush tables,其实没有关闭文件的含义,只是mysiam的handler close接口刚好会尝试关闭MYD,MYI文件, 这个操作对InnoDB表并没有什么卵用。

    分区表过多,也是属于myisam表的缺陷,分区多少也应该和open file数量没什么关系。

    如何查看mysqld进程打开的文件数?

    假设pid = 26206

    ls /proc/26206/fd | wc -l

    在MySQL中,有几个地方会存在文件描述符限制:

    1、在Server层,整个mysqld实例打开文件总数超过用户进程级的文件数限制,需要检查内核 fs.file-max 限制、进程级限制 ulimit -n 及MySQL中的 open-files-limit 选项,是否有某一个超限了。任何一个条件超限了,就会抛出错误。

    2、虽然Server层总文件数没有超,但InnoDB层也有限制,所有InnoDB相关文件打开总数不能超过 innodb-open-files 选项限制。否则的话,会先把最早打开的InnoDB文件描述符关闭,才能打开新的文件,但不会抛出错误,只有告警信息。

    相应地,如果提示超出限制,则可以使用下面方法提高上限:

    1、首先,提高内核级总的限制。执行:sysctl -w fs.file-max=3264018;
    
    2、其次,提高内核对用户进程级的打开文件数限制。执行:ulimit -n 204800;
    
    3、最后,适当提高MySQL层的几个参数:open-files-limit、innodb-open-files、table-open-cache、table-definition-cache。
     

    1、open-files-limit
    它限制了mysqld进程可持有的最大打开文件数,相当于是一个小区的总电闸,一旦超限,小区里所有住户都得停电。
    5.6.7(含)以前,默认值0,最大和OS内核限制有关;
    5.6.8(含)以后,默认值会自动计算,最大和OS内核限制有关。

    在5.6.8及以后,其自动计算的几个限制规则见下,哪个计算结果最大就以哪个为上限:

    1) 10 + max_connections + (table_open_cache * 2)
    2) max_connections * 5
    3) open_files_limit value specified at startup, 5000 if none
    

    2、innodb-open-files

    限制InnoDB引擎中表空间文件最大打开的数量,相当于自己家中电箱里的某个电路保险,该电路短路的话,会自动跳闸,而不会影响其他电路,去掉短路源后重新按上去就可以使用。

    其值最低20,默认400,只计算了包含ibdata*、ib_logfile*、*.ibd 等三类文件,redo log不计算在内,5.6以后可独立undo log,我还未进行测试,应该也不会被计算在内,有兴趣的朋友可验证下。

    3、table-definition-cache

    该cache用于缓存 .frm 文件,该选项也预示着 .frm 文件同时可打开最大数量。
    5.6.7 以前默认值400;
    5.6.7 之后是自动计算的,且最低为400,自动计算公式:400 + (table-open-cache / 2)。

    对InnoDB而言,该选项只是软性限制,如果超过限制了,则会根据LRU原则,把旧的条目删除,加入新的条目。

    此外,innodb-open-files 也控制着最大可打开的表数量,和 table-definition-cache 都起到限制作用,以其中较大的为准。如果没配置限制,则通常选择 table-definition-cache 作为上限,因为它的默认值是 200,比较大。

    4、table-open-cache

    该cache用于缓存各种所有数据表文件描述符。
    5.6.7 以前,默认值400,范围:1 – 524288;
    5.6.8 – 5.6.11,默认值2000,范围:1 – 524288;
    5.6.12以后,默认值2000(且能自动计算),范围:1 – 524288。

    补充说明1:关于如何计算表文件描述符的建议:

    table-open-cache 通常和 max-connections 有关系,建议设置为 max_connections * N,N的值为平均每个查询中可能总共会用到的表数量,同时也要兼顾可能会产生临时表。

    补充说明2:MySQL会在下列几种情况把表从table cache中删掉:

    1、table cache已满,并且正要打开一个新表时;
    2、table cache中的条目数超过 table_open_cache 设定值,并且有某些表已经长时间未访问了;
    
    3、执行刷新表操作时,例如执行 FLUSH TABLES,或者 mysqladmin flush-tables 或 mysqladmin refresh
    

    补充说明3:MySQL采用下述方法来分配table cache:

    1、当前没在用的表会被释放掉,从最近最少使用的表开始;
    2、当要打开一个新表,当前的cache也满了且无法释放任何一个表时,table cache会临时加大,临时加大的table cache中的表不用了之后,会被立刻释放掉。
     
  • 相关阅读:
    linux性能优化参数小节
    java并发编程知识点备忘
    编码之痛:操作系统迁移后redis缓存无法命中
    jetty8 text/plain默认字符编码的坑
    设计数据密集型应用笔记1:可靠 可扩展可维护的应用
    使用异步任务降低API延迟_实践总结
    常用失败控制模式
    使用maven插件构建docker镜像
    做几道美团校招题
    Boyer-Moore字符串查找算法的实现
  • 原文地址:https://www.cnblogs.com/yuyue2014/p/4783553.html
Copyright © 2011-2022 走看看