Переполнение временного каталога tmpdir сервера mysql

archive view archive save

mysql_logo_230x260.jpg В данном примере tmpdir размещён в оперативной памяти (РАМ), под который выделено 512 МБ и их стало нехватать: 1021 Disk full (/var/mysqltmp/#sql_546e_10.MAI); waiting for someone to free some space... (errno: 28 No space left on device).

MySQL сервер переваривает 3 БД, одна из которых отведена движку статистики Matomo под который разработчиком рекомендуется выделять отдельный физический (не виртуальный, не VPS) сервер БД!

Но, «маем, те шо маем», MySQL сервант один на всех и без малого лет 5 все те 3 БД вместе с Matomo как-то уживались на 512 МБ tmpdir. С тех пор материалов и прочих данных прилично наросло и 512 МБ стало мало, каталог tmpdir переполнился временными файлами, попёрло ошибками движка и MySQL сервера: 1021 Disk full (/var/mysqltmp/#sql_546e_10.MAI); waiting for someone to free some space... (errno: 28 No space left on device)

Кто виноват и как «лечить»

Ответ очевиден, добавить места для tmpdir, а если tmpdir переполнился и наглухо забит «залипшими» там временными файлами, то восстановить работу можно только ручным удалением содержимого или перезапуском сервера при котором tmpdir будет очищен автоматически.

tmpdir в mysql используется в ходе сортировки/выборки данных выходящих за пределы конфигурации лимитов РАМ для стандартных рабочих нагрузок.

"mysql tmpdir file lifetime" - оф.документация умалчивает о том, как долго хранятся временные файлы в tmpdir.

Вывод о том, что временные файлы обычно не хранятся там постоянно и автоматически удаляются после завершения сортировки/выборки данных, можно сделать наблюдая пустые tmpdir директории:

$ sudo ls -la /var/mysqltmp
total 4
drwx------ 2 mysql mysql 40 Aug 3 09:31 .
drwxr-xr-x 14 root root 4096 Aug 2 22:00 ..
$ sudo ls -la /var/mysqltmp2
total 8
drwx------ 2 mysql mysql 4096 Aug 3 09:31 .
drwxr-xr-x 14 root root 4096 Aug 2 22:00 ..

а также того факта, что временные файлы там использовались и отмечены как "deleted" но не удалены полностью:

$ sudo lsof +L1|grep mysql
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NLINK NODE NAME
mysqld 30090 mysql 7u REG 8,1 0 0 1061632 /var/mysqltmp2/ibytNr6B (deleted)
mysqld 30090 mysql 8u REG 0,42 0 0 247056902 /var/mysqltmp/ib2LhTxZ (deleted)
mysqld 30090 mysql 9u REG 0,42 0 0 247056926 /var/mysqltmp/ibRL0lGK (deleted)
mysqld 30090 mysql 13u REG 8,1 0 0 1061640 /var/mysqltmp2/ibVFSJq8 (deleted)

Файловый дескриптор (FD) между вызывающим процессом и файлом открыт, файл и его содержимое фактически ещё на диске, доступ к содержимому «(deleted)» файла может быть восстановлен.

Спецификация ФС Unix такова, что физически файл и его содержимое удаляется с диска только тогда, когда количество процессов, открывших файл и количество ссылок на файл равно 0.

Здесь сразу ответ на вопрос: «Почему не освободилось место на диске после удаления файла?». lsof поможет обнаружить не до конца удалённые файлы, а также процессы на них ссылающиеся.

Из вышеизложенного приходим к обоснованному умозаключению, что переполнение директории tmpdir могло произойти по нескольким причинам:

  • активной одновременной нагрузке роботов сканирующих сайты на сервере;
  • добавления к рабочей нагрузке БД пользовательской сортировки/выборки данных, например выборка отчётов за большой период времени в том же "матомо", запуск по "крону" сервисных скриптов "матомо" и т.п.

«Залипание» временных файлов в tmpdir и необходимость ручной очистки (перезапуск сервера) вызвано обрывом процесса сортировки/выборки данных, ведь автоматическое удаление временных файлов из tmpdir возможно только после успешного, а не аварийного завершения сортировки/выборки данных: waiting for someone to free some space... (errno: 28 No space left on device) - не дождавшись «free some space...» процесс mysql испустил «errno: 28 No space left on device» так и недоделав своё дело до конца, файловые дескрипторы (FD) открыты, место занято.

Подобные случаи приводят к идее использовать несколько временных директорий, одну в оперативке как основную, и вторую на физической ФС как резервную - благо схема "round-robin fashion", как то сказано в документации, позволяет данную мысль реализовать.

Делаем второй каталог, ставим на него нужные "чмоды", изменяем конфиг, перезапускаем сервер.

$ sudo mkdir /var/mysqltmp2
 
$ sudo chown mysql:mysql /var/mysqltmp2
 
$ sudo chmod 700 /var/mysqltmp2
 
$ sudo vi /etc/mysql/my.cnf
...
tmpdir = /var/mysqltmp:/var/mysqltmp2
 
$ sudo systemctl restart mysql

АдМинь!


Об авторе
АдМинь БагоИскатель
АдМинь БагоИскатель ярый борец за безглючную работу любых механизмов и организмов во всей вселенной и потому пребывает в вечном поиске всяческих багов, а тот кто ищет как известно всегда находит. Когда что-то или кого-то вылечить не в состоянии, то со словами "Я в аду, а вы все черти" уходит в запой выйдя из которого снова берётся лечить неизлечимое.
Ещё статьи автора

Нет комментариев

Вы можете стать первым, кто добавит комментарий к этой записи.

Добавить комментарий

АХТУНГ! Все комменты гостей модерасятся модерастом.
  1. Мессаги исключительно рекламного содержания, либо содержащие только одни оценочные суждения типа "круто" ("отлично", "спасибо", "автор дебил" и т.п.) не публикуются;
  2. Злостным спамерам, пранкерам и прочей сетевой нечисти рекомендуем напрасно не тратить своего времени и удовлетворять свои больные фантазии на специализированных Интернет ресурсах!;
  3. Разумная обоснованная критика, замечания, дополнения приветствуются. Поля помеченные символом * обязательны к заполнению.


Защитный код
Обновить

Комментарии в блоге
Новое на форуме