您的位置:首页 > 数据库 > SQL

mysql open files

2015-09-05 17:38 483 查看
错误信息如下:

.....
15090513:10:17[ERROR]/usr/local/mysql/bin/mysqld:Can'topenfile:'./mytest/t1.frm'(errno:24)
15090513:10:17[ERROR]/usr/local/mysql/bin/mysqld:Can'topenfile:'./mytest/t2.frm'(errno:24)
......
15090513:10:17[ERROR]Errorinaccept:Toomanyopenfiles
....

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

[root@myplace]#/usr/local/mysql/bin/perror24
OSerrorcode24:Toomanyopenfiles

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

[root@myplace]#sysctl-wfs.file-max=43621
[root@mypalce]#sysctl-a|grepfs.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选项无法生效,因为内核限制了普通用户的最多打开文件数.

目前openfile超过limit的问题:

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

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

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

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

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

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

如何查看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-wfs.file-max=3264018;

2、其次,提高内核对用户进程级的打开文件数限制。执行:ulimit-n204800;

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_limitvaluespecifiedatstartup,5000ifnone


2、innodb-open-files

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

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

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会在下列几种情况把表从tablecache中删掉:

1、tablecache已满,并且正要打开一个新表时;
2、tablecache中的条目数超过table_open_cache设定值,并且有某些表已经长时间未访问了;

3、执行刷新表操作时,例如执行FLUSHTABLES,或者mysqladminflush-tables或mysqladminrefresh


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

1、当前没在用的表会被释放掉,从最近最少使用的表开始;

2、当要打开一个新表,当前的cache也满了且无法释放任何一个表时,tablecache会临时加大,临时加大的tablecache中的表不用了之后,会被立刻释放掉。


                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: