MySQL Ошибка 1030 (HY000): Got error 28 from storage engine (No space left)
Природа системного кода ошибки ОС Linux Errno 28 в MySQL
Системная ошибка MySQL Error 1030 (SQLSTATE HY000): «Got error 28 from storage engine» является прямой трансляцией стандартного кода возврата ядра Linux POSIX ENOSPC (Error 28: No space left on device). Когда движок хранения InnoDB или MyISAM пытается выполнить операцию записи данных, расширения файла табличного пространства или создания дисковой временной таблицы в каталоге /tmp (tmpdir), а на целевом дисковом накопителе физически заканчиваются свободные блоки или исчерпаны индексные дескрипторы (Inodes), операция аварийно прерывается.
Бизнес-риски
Полный перевод базы данных в режим Read-Only, повреждение страниц данных InnoDB при незавершенной записи, краш демона mysqld и недоступность корпоративных систем.
Распространенные источники заполнения диска при ошибке 28
| Источник проблемы | Типичное расположение | Способ очистки / решения |
|---|---|---|
| Разрастание бинарных логов (Binlogs) | /var/lib/mysql/binlog.* | Настройка binlog_expire_logs_seconds и PURGE BINARY LOGS. |
| Тяжелые дисковые временные таблицы | /tmp или tmpdir (часто монтируется в RAM) | Перенос tmpdir на объемный раздел диска. |
| Исчерпание файловых инодов (Inodes) | Корневая файловая система / | Удаление миллионов мелких файлов сессий/кэша. |
Регламент экстренного освобождения диска и устранения ошибки 28
Сценарий 1: Экспресс-диагностика дискового пространства и Inodes
Определите переполненную файловую систему:
# 1. Проверка свободного места в гигабайтах:
df -h
# 2. Проверка свободных дескрипторов (Inodes):
df -i
# Если IUse% = 100% -> диск переполнен мелкими файлами, даже если есть свободные Гб!Сценарий 2: Очистка и ротация бинарных логов (Binary Logs)
Никогда не удаляйте binlog-файлы напрямую через rm в терминале! Используйте команды СУБД:
-- 1. Подключитесь к MySQL:
mysql -u root -p
-- 2. Удаление бинарных логов старше 2 дней:
PURGE BINARY LOGS BEFORE NOW() - INTERVAL 2 DAY;
-- 3. Настройка автоматического удаления старых логов через 3 дня (в MySQL 8.0):
SET GLOBAL binlog_expire_logs_seconds = 259200;
-- 4. Персистентное сохранение в my.cnf:
-- sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf
-- binlog_expire_logs_seconds = 259200Сценарий 3: Перенос временного каталога MySQL (tmpdir) на отдельный раздел
Если каталог /tmp смонтирован в tmpfs небольшого объема (например, 1–2 Гб), тяжелые временные таблицы переполняют его за секунды:
# 1. Создание нового просторного каталога под временные таблицы:
sudo mkdir -p /var/lib/mysql-tmp
sudo chown -R mysql:mysql /var/lib/mysql-tmp
sudo chmod 1777 /var/lib/mysql-tmp
# 2. Указание нового пути в my.cnf:
sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf
[mysqld]
tmpdir = /var/lib/mysql-tmp
# 3. Перезапуск MySQL:
sudo systemctl restart mysqlТиповые ошибки администраторов
- Удаление активных log-файлов через rm: Удаление открытого процессами лога (например,
/var/log/mysql/error.log) не освобождает место на диске до тех пор, пока процессmysqldне будет перезапущен (файл удерживается дескриптором). Очищайте логи командойsudo truncate -s 0 /var/log/mysql/error.log. - Размещение tmpdir в корневой файловой системе без квот: Один неоптимизированный запрос без индексов может сгенерировать временную таблицу на 100 Гб и полностью парализовать всю ОС Linux.
Специалисты ITSTM оперативно очистят логи, перенесут таблицы на дополнительные блочные хранилища (LVM/NVMe) и настроят мониторинг свободного места.
Частые вопросы (FAQ)
Почему df -h показывает свободное место, но MySQL выдает Got error 28?
Проверьте команду df -i. Если закончились файловые дескрипторы (Inodes), файловая система блокирует создание новых файлов даже при наличии сотен гигабайт свободного места.
Как найти самые большие папки и файлы на диске?
Выполните команду: sudo du -ahx / | sort -rh | head -n 20.
Безопасно ли удалять файлы relay-log на реплике?
Удалять их вручную нельзя. Настройте параметры relay_log_purge = 1 и relay_log_space_limit в конфигурации реплики.
Что делать, если каталог /tmp переполняется каждые несколько минут?
Включите slow query log, найдите запрос с большим значением Rows_examined и добавьте необходимые композитные индексы, чтобы запрос не создавал временных таблиц на диске.