Linux – How to set OOM killer adjustments for daemons permanently

daemonlinux-kernelout of memory

Running some Linux servers with single or just a few vital system service daemons, I would like to adjust the OOM killer for those daemonized processes in case something odd happens. For example, today some Ubuntu server running MySQL got a killed MySQL daemon because tons of apt-checker processes were consuming all memory and the kernel thought it was a good idea to kill MySQL.

I know I can adjust the score using the /proc/$(pidof mysqld)/oom_score_adj file to give the kernel some clue I don't prefer MySQL to be killed, yet that doesn't survive a restart of the service. Should I edit init/upstart scripts from the package to include these adjustments? I don't think that's a very elegant solution as I would make adjustments to files belonging to a package. Would it be possible to hook into upstart/init scripts in general and conditionally adjust it? Or would you suggest running an indefinite script like while true{ adjust_oom(); sleep 60;}?

Best Answer

Several modern dæmon supervision systems have a means for doing this. (Indeed, since there is a chain loading tool for the job, arguably they all have a means for doing this.)

  • Upstart: Use oom score in the job file.
    oom score -500
  • systemd: Use the OOMScoreAdjust= setting in the service unit. You can use service unit patch files to affect pre-packaged service units.
    [Service]
    OOMScoreAdjust=-500
  • daemontools family: Use the oom-kill-protect tool from the nosh toolset in the run program for the service.

    If you are converting a system service unit, the convert-systemd-units tool will in fact convert the OOMScoreAdjust= setting into such an invocation of oom-kill-protect.

    #!/bin/nosh

    oom-kill-protect -- -500

    program arguments
    As a bonus, you can make it parameterizable:
    oom-kill-protect -- fromenv
    and set the value of the parameter in the service's environment (presumed to be read from an envdir associated with the service, here manipulated with the nosh toolset's rcctl shim):
    rcctl set servicename oomprotect -500

Further reading

Related Question