В данном примере 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
поможет обнаружить не до конца удалённые файлы, а также процессы на них ссылающиеся.
- Why is space not being freed from disk after deleting a file in Red Hat Enterprise Linux? - Red Hat Customer Portal
- unlink (Unix) - Wikipedia
- rm (Unix) - Wikipedia
Из вышеизложенного приходим к обоснованному умозаключению, что переполнение директории 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
АдМинь!