Out of memory и принудительное завершение процесса MySQL

Часто при анализе неполадок на сервере в выводе утилиты dmesg приходится встречать сообщения о OOM и прекращении ядром процесса MySQL. Применительно к MySQL Out of memory (OOM)  — ситуация при которой системе не хватает оперативной памяти для нормального функционирования, при возникновении подобной ситуации ядро «убивает» MySQL. Процесс MySQL будет завершен если система сочтет его самым малозначительный процессом

 

Mysql Out of memory

 

В случае если сервер используется для размещения веб-сайтов ресурсы при этом становятся недоступны поскольку пропадает соединение с сервером баз данных. Вместо контента сайтов может отображаться ошибка 500 или ошибка о невозможности подключиться к базе данных.

 

Чаще всего вопрос решается запуском MySQL

service mysql start

Однако, часто при «убийстве» процесса ядром происходит повреждение таблиц баз данных. Обычно их можно починить используя утилиту myisamchk, но случаются и ситуации когда MySQL не запускается и после починки таблиц.

 

Работы по устранению неисправностей в этом случае могут занять определенное время, сайты на сервере при этом будут продолжать оставаться недоступны.

 

 

MySQL Out of memory и как предотвратить убийство процесса 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 мы поместили процесс в группу, группу затем добавили в подсистему.

Самым лучшим решением если подобные ситуации появляются регулярно является перенос проектов на машину с большим количеством оперативной памяти.

 

Читайте про то как исправить таблицы после сбоя если они имеют тип InnoDB (упомянутая утилита myisamchk в этом случае не поможет).