Часто при анализе неполадок на сервере в выводе утилиты dmesg приходится встречать сообщения о OOM и прекращении ядром процессов MySQL. Ошибка Out of memory MySQL — ситуация при которой системе не хватает оперативной памяти для нормального функционирования, при возникновении подобной ситуации ядро принудительно завершает процесс MySQL. Процесс MySQL будет завершен если система сочтет его самым малозначительный процессом.
В случае если сервер используется для размещения веб-сайтов ресурсы при этом становятся недоступны поскольку пропадает соединение с сервером баз данных. Вместо контента сайтов может отображаться ошибка 500 или ошибка о невозможности подключиться к базе данных.
Чаще всего вопрос решается запуском MySQL
service mysql start
Однако, часто при «убийстве» процесса ядром происходит повреждение таблиц баз данных. Обычно их можно починить используя утилиту myisamchk, но случаются и ситуации когда MySQL не запускается и после починки таблиц.
Работы по устранению неисправностей в этом случае могут занять определенное время, сайты на сервере при этом будут продолжать оставаться недоступны.
В Linux существует возможность дать ядру указание на то какие процессу убивать не следует. При необходимости можно задать в качестве такого процесса процесс, выполняемый от имени сервера баз данных.
Делается это при помощи cgroups или cgroup (начиная с версии ядра 4.5).
В рамках статьи вдаваться в особенности работы cgroups не будем, приведем лишь способ решения поставленной задачи — ограждение процесса MySQL от убийства ядром.
Добавим в tasks идентификатор процесса MySQL
ps aux | grep mysql
В выводе видим нужный PID, помещаем его в tasks
echo PID > /sys/fs/cgroup/cpuset/group0/tasks
где PID — идентификатор процесса
cgroups позволяет управлять памятью, в том числе создавать ограничения для механизма срабатывающего при нехватке RAM:
echo 1 > /sys/fs/cgroup/memory/group0/memory.oom_control
cat /sys/fs/cgroup/memory/group0/memory.oom_control
oom_killdisable 1
under_oom 0
При преувеличении потребления памяти сейчас процесс убит не будет, ядро выберет другую жертву и принудительно завершит работу другой службы, серверу баз данных и таблицам БД угрожать при выполнении описанных действий ничего не будет.
Используя cgroups мы поместили процесс в группу, группу затем добавили в подсистему.
Самым лучшим решением если подобные ситуации появляются регулярно является увеличение количества RAM.
Читайте про то как исправить таблицы после сбоя если они имеют тип InnoDB (упомянутая утилита myisamchk в этом случае не поможет).