最近在论坛里面看到有几个朋友都发帖求助,原因是mysql报错:[ERROR] Error in accept: Two many open files。而且这位朋友还说他并没有同时打开这么多文件,那么这是什么原因呢?
首先,我们需要了解的是,在linux里面打开文件是以文件描述符(FD,file descripter)的形式打开的,每打开一次文件,那么os就分配给你一个文件描述符,对于同一个文件如果有多个进程打开,那么就可以分配多个文件描述符。好了,现在我们回到这个问题上,这位朋友说他并没有一次性打开这么多的文件,怎么会出现这个问题呢?刚才说了,每个进程打开同一个文件都可能分配一个独立的FD,而mysql正是这么做的,每个session开打的数据文件的描述符都是独立的,而对于索引文件则是所有的session共享,
我先将手册里面的原话贴出来:
MySQL is multi-threaded, so there may be many clients issuing queries for a given table simultaneously. To minimize the problem with multiple client sessions having different states on the same table, the table is opened independently by each concurrent session. This uses additional memory but normally increases performance. WithMyISAMtables, one extra file descriptor is required for the data file for each client that has the table open. (By contrast, the index file descriptor is shared
between all sessions.)
好了,那你现在应该明白了,为什么并没有同时打开那么文件,但是却有那么多的文件描述符。弄清楚问题,那么现在就来解决这个问题。首先是增大
open_files_limit,具体用法参考手册上说明,然后根本解决方法是在os上增大mysqld这个线程的最大开打文件数,在linux里面可以通过编辑文件 /etc/security/limits.conf然后里面的信息如下:
# /etc/security/limits.conf
#
#Each line describes a limit for a user in the form:
#
#<domain> <type> <item> <value>
#
#Where:
#<domain> can be:
# - an user name
# - a group name, with @group syntax
# - the wildcard *, for default entry
# - the wildcard %, can be also used with %group syntax,
# for maxlogin limit
#
#<type> can have the two values:
# - "soft" for enforcing the soft limits
# - "hard" for enforcing hard limits
#
#<item> can be one of the following:
# - core - limits the core file size (KB)
# - data - max data size (KB)
# - fsize - maximum filesize (KB)
# - memlock - max locked-in-memory address space (KB)
# - nofile - max number of open files
# - rss - max resident set size (KB)
# - stack - max stack size (KB)
# - cpu - max CPU time (MIN)
# - nproc - max number of processes
# - as - address space limit
# - maxlogins - max number of logins for this user
# - maxsyslogins - max number of logins on the system
# - priority - the priority to run user process with
# - locks - max number of file locks the user can hold
# - sigpending - max number of pending signals
# - msgqueue - max memory used by POSIX message queues (bytes)
# - nice - max nice priority allowed to raise to
# - rtprio - max realtime priority
#
#<domain> <type> <item> <value>
#
这个里面可以对进程需要的很多资源进行配置,比如说我们现在需要就是onfile这个选项open file而且我们有两种配置方式,第一是针对用户组的形式,第二具体用户的形式
比如有mysql用户
mysql soft nofile 131072
上面就限制了mysql用户最大的打开文件数。同时可以通过ulimit -a命令来查看这些信息。
同时需要注意的是,上面配置的用户级别打开FD的个数,系统级别的FD最大打开数可以通过 cat /proc/sys/fs/file-max查看,编辑有两种方式:
1. echo n > /proc/sys/fs/file-max
2. vi /etc/sysctl.conf 然后添加一行 fs.file-max=n 然后使用sysctl -p使其生效
但有时候,我们遇到的不是two many open files 而是 two many connections,这个就是并发的连接数,通过修改参数mysql的max_connections来解决,但是需要注意的是当这个参数增大的时候,同时可能会引发two many open files的问题,原因上面已经解释过了。自己并没有遇到过这个问题,只是简单模拟了一下,如果有错误,欢迎指正。