rueckstiess / mtools

A collection of scripts to set up MongoDB test environments and parse and visualize MongoDB log files.
Apache License 2.0
1.88k stars 397 forks source link

Question regarding file descriptors and other kernel parameters required by MongoDB #907

Closed thommy66 closed 1 year ago

thommy66 commented 1 year ago

Hi guys, First of all thanks for providing mtools, I am a happy user of it on serveral Mac's! I need to increase my file descriptors since the default seems to be only 256 while 64000 are recommended. On my Mac (Studio with M1 chip) I get from time to time an error saying "too many files open" which is due to the above setting

[services] ulimit -a
-t: cpu time (seconds)              unlimited
-f: file size (blocks)              unlimited
-d: data seg size (kbytes)          unlimited
-s: stack size (kbytes)             8176
-c: core file size (blocks)         0
-v: address space (kbytes)          unlimited
-l: locked-in-memory size (kbytes)  unlimited
-u: processes                       10666
-n: file descriptors                256

The mongodb documentation describes what to do if services are installed using brew but what do I need to do when using mtools? Questions

I searched the web and found many different solutions, depending on the MacOS Version. For Ventura (13.1.x) I found a crazy complicated one instruction which requires 4 reboots and entering the recovery mode twice... Can't belive it is so complicated...

Thanks a lot for your help and maybe an update in the mtools documentation could be very helpful too.

stennie commented 1 year ago

Hi @thommy66,

Operating system settings like ulimit are configured and managed outside of mtools, so you would have to find some instructions specific to the version of macOS you are running. I expect the approach will be the same for either Intel or Apple Silicon CPUs.

mlaunch is only intended for local test and dev deployments, so if you are working with a larger data set you may find it easier to use Brew to manage a persistent deployment. I believe brew services wraps launchctl so it is more straightforward to adjust limits without messing with reboots or csrutil (which modifies System Integrity Protection settings).

You could also try searching or asking for advice on Ask Different (Stack Exchange for macOS) or perhaps the MongoDB Developer Community Forums.

If you find or create a reasonable set of instructions, please add a comment on this issue with a pointer.

Regards, Stennie

thommy66 commented 1 year ago

Hi @stennie Thanks for the feedback, unfortunately it is not so easy. And there are good reasons, why I use mtools instead of brew. I did not find a way to start multiple instances of mongod, each with a separate mongod.conf file specifing a different port for each node of the ReplicaSet using brew. So mtools delivers that flexibilty which made it the right tool for my dev-work.

However, the limitation of 256 open files is definitely a strong limitation. I need a replicaset with the minimal three nodes since I use transactions in MongoDB and want to test and debug them in my IDE. I have only a handful of databases in each node and I cannot execute more than around 50 statements and then the entire setup crashes with "too many files open". This is far away from a 'big installation'.

So I did some more research. I agree with many people in the net, that it is not very wise to change low level system settings such as increasing system wide max file descriptors. It may also slow down the entire machine. Generally the OS is pretty good in managing the resources of the machine... So I guess its better not to use csrutil etc.

I found something easier which seems to work. I only increased the max number of file descriptors to 8192 for the moment. Seems to be enough for me at the moment. Here is what to do on a MAC computer:

#check the current limits in the shell
ulimit -a

# ATTN: use this folder in the System and NOT in your home folder! You need `sudo` (`root` access) to create and save
# files there
cd /Library/LaunchDaemons
sudo touch limit.maxfiles.plist
# start your editor and then add the following to the above file
# e.g. nano limit.maxfiles.plist  or whatever editor you prefer
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple/DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
  <plist version="1.0">
    <dict>
      <key>Label</key>
        <string>limit.maxfiles</string>
      <key>ProgramArguments</key>
        <array>
          <string>launchctl</string>
          <string>limit</string>
          <string>maxfiles</string>
          <string>8192</string>
          <string>81920</string>
        </array>
      <key>RunAtLoad</key>
        <true />
      <key>ServiceIPC</key>
        <false />
    </dict>
  </plist>

# to save the file you may need to provide the password again.
# REBOOT the computer

After the reboot my ulimit shows better values for MongoDB:

[LaunchDaemons] ulimit -a
-t: cpu time (seconds)              unlimited
-f: file size (blocks)              unlimited
-d: data seg size (kbytes)          unlimited
-s: stack size (kbytes)             8176
-c: core file size (blocks)         0
-v: address space (kbytes)          unlimited
-l: locked-in-memory size (kbytes)  unlimited
-u: processes                       10666
-n: file descriptors                8192

Maybe this helps somebody else...

stennie commented 1 year ago

Thanks for sharing a solution @thommy66 !

FYI, you can also use a single member replica set for testing transactions in a dev environment.

Regards, Stennie