Переполнение временного каталога 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. Разумная обоснованная критика, замечания, дополнения приветствуются. Поля помеченные символом * обязательны к заполнению.


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

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

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

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