MongoDB "Too Many Open Files"? Raise the limit
This blog post is intended to supplement the "Too Many Open Files" page in the mongoDB docs.
Raising the file limit for MongoDB
If you installed from the Ubuntu/Debian package, then there is a simple way to increase the open file limit. MongoDB's startup script is /etc/init/mongodb.conf. This is an upstart script which supersedes the /etc/init.d scripts we're all use to. All you need to do is add "ulimit -n {X}" to the script block before mongodb is launched, replacing X with the limit you want (I use 65000). That sets the ulimit for the script and any processes it launches (therefore mongodb). Here is an example /etc/init/mongodb.conf
# Ubuntu upstart file at /etc/init/mongodb.conf
pre-start script
mkdir -p /db/mongodb/
mkdir -p /var/log/mongodb/
end script
start on runlevel [2345]
stop on runlevel [06]
script
ulimit -n 65000
ENABLE_MONGODB="yes"
if [ -f /etc/default/mongodb ]; then . /etc/default/mongodb; fi
if [ "x$ENABLE_MONGODB" = "xyes" ]; then
exec start-stop-daemon --start --quiet --chuid mongodb --exec /usr/bin/mongod -- --config /etc/mongodb.conf
fi
end script
Once mongoDB is up, you can check the limit for the process by doing cat /proc/{pid}/limit. Replace {pid} with the pid of mongoDB. To get the pid, just do "ps axu | grep mongodb".
If you aren't using the install packages, then you'll need to add the ulimit command to your own startup script. Keep in mind that ulimit is a bash command, not a regular binary tool, so look at "man bash" for more info on ulimit.
This blog post suggests that you can set system wide limits by editing /etc/security/limits.conf and /etc/pam.d/common-session, however, this only applies interactive and non-interactive shells (and processes started by them). When using just this technique, it didn't appear to affect the open file limit of the mongodb process started by the default upstart script (without my added ulimit statement).
If you want to try system wide limits, then add a line like the following to /etc/security/limits.conf:
* - nofile 65000
See "man limits.conf" for more info.
In /etc/pam.d/common-session, enable the limits module by adding:
session required pam_limits.so
Keep in mind that all this really does is have PAM set the limit for interactive and non-interactive shells when loaded. Processes then pickup these limits when started from shells/scripts. You should probably do a restart to fully enact these settings. If someone out there gets system wide settings to apply to mongoDB, let me know with a comment.
Update:
It occurred to me after writing this post that you should put "ulimit -n 65000" in /etc/default/mongodb. If that file doesn't exist, create it. This is the proper place for it. As you can see in the upstart file, it will run /etc/default/mongodb if it exists before it launches mongodb.