MySQL: заканчивается место под данные — причины и решение
Диск забит под ноль, база встала, сайт отдаёт ошибки записи: MySQL заканчивается место под данные. Переполненный диск не только останавливает базу, но и рискует повредить таблицы, поэтому решать нужно быстро. Хорошая новость — чаще всего место съедают предсказуемые вещи: бинлоги, разросшийся общий файл InnoDB или пара больших таблиц. Разберём, как найти пожирателя и освободить диск без потери данных.
Содержание
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Первое действие: найдите, что заняло место
Не удаляйте наугад — сначала посмотрите, где именно кончилось место и что его съело. Проверьте разделы и крупнейшие каталоги базы:
df -h
du -sh /var/lib/mysql/* | sort -rh | head -n 15
df -h покажет, какой раздел заполнен, а du — что внутри каталога данных MySQL занимает больше всего. Вы сразу увидите картину: огромные бинлоги (mysql-bin.*), раздутый ibdata1, конкретная большая база или таблица. Это ваш диагноз. Дальше действуйте по тому, что нашли: у разных пожирателей — разные способы очистки. Главное правило при переполнении — освобождать место безопасно, а не сносить файлы базы вручную, иначе можно потерять данные.
Причина 1: разрослись бинарные логи
Очень частый виновник — бинарные логи (binary logs). MySQL пишет в них все изменения для репликации и восстановления, и без ротации они копятся месяцами, съедая десятки гигабайт. Если du показал большие mysql-bin.NNNNNN, безопасно удалите старые средствами самого MySQL (не командой rm, чтобы не сломать индекс логов):
PURGE BINARY LOGS BEFORE NOW() - INTERVAL 3 DAY;
Это удалит бинлоги старше трёх дней. Если репликация не используется вовсе, бинлоги можно либо отключить, либо задать автоматическое удаление через binlog_expire_logs_seconds, чтобы они не копились. Именно неограниченные бинлоги — причина номер один внезапной нехватки места под MySQL. Настроив их автоматическую очистку, вы закрываете эту проблему навсегда. Удалять их вручную через rm нельзя — только через PURGE.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США и РФ. Оплата картой РФ и по СБП.
Арендовать VPS под базуПричина 2: раздутый ibdata1
Если вы видите гигантский файл ibdata1, дело в том, что раньше InnoDB хранил все таблицы в одном общем файле, который только растёт и не отдаёт место обратно, даже когда данные удалены. Проверьте, включён ли режим отдельных файлов на таблицу:
SHOW VARIABLES LIKE 'innodb_file_per_table';
Если ON (современный дефолт) — новые таблицы хранятся в отдельных файлах, и это правильно. Но уже раздутый ibdata1 сам по себе не сожмётся: чтобы вернуть место, нужно снять полный дамп всех баз, остановить MySQL, удалить старые файлы InnoDB и восстановить базы из дампа заново — тогда данные лягут в отдельные файлы, а ibdata1 станет маленьким. Это трудоёмкая процедура, требующая бэкапа и осторожности, поэтому её делают планово. Для срочного освобождения места сначала займитесь бинлогами и большими таблицами — обычно этого достаточно.
Причина 3: конкретная таблица разрослась
Иногда место съедает одна-две большие таблицы: логи, история, аналитика, очередь, которую забыли чистить. Найдите крупнейшие таблицы по всей базе:
SELECT table_schema, table_name,
ROUND((data_length+index_length)/1024/1024) AS size_mb
FROM information_schema.tables
ORDER BY size_mb DESC LIMIT 15;
Запрос покажет самые тяжёлые таблицы в мегабайтах. Дальше решайте по смыслу: старые логи и историю можно архивировать или удалять, лишние данные — чистить, а по-настоящему нужные большие таблицы — партиционировать или выносить. После массового удаления строк из InnoDB-таблицы место на диске сразу не вернётся; чтобы физически освободить его, выполните OPTIMIZE TABLE имя; — она пересоберёт таблицу. Это частый сюрприз: строки удалили, а диск не освободился, пока не пересобрали таблицу.
Причина 4: временные файлы и общие логи
Место могут занимать и служебные файлы: общий лог запросов (general_log), если его случайно включили и забыли, лог медленных запросов без ротации, временные файлы тяжёлых сортировок. Проверьте, не пишется ли общий лог, который в норме должен быть выключен:
SHOW VARIABLES LIKE 'general_log%';
Если general_log = ON на боевом сервере — почти всегда это ошибка: он пишет каждый запрос и растёт очень быстро. Выключите его. Лог медленных запросов полезен, но и он требует ротации, чтобы не разрастаться. Временные файлы сортировок появляются при тяжёлых запросах без индексов — это ещё один повод оптимизировать запросы. Уберите лишнее логирование, настройте ротацию журналов — и служебные файлы перестанут отъедать диск.
Как безопасно освободить место прямо сейчас
Если база встала из-за переполнения, действуйте по приоритету безопасного освобождения. Сначала очистите старые бинлоги через PURGE — это обычно возвращает больше всего места мгновенно и без риска. Затем уберите лишние логи и почистите пакетный кэш системы вне каталога MySQL:
apt clean
journalctl --vacuum-size=200M
Освободив несколько гигабайт, запустите MySQL и уже спокойно, из работающей базы, займитесь коренными причинами: большими таблицами, ротацией бинлогов, при необходимости — пересборкой ibdata1. Ни в коем случае не удаляйте файлы ib_logfile, ibdata1 или файлы таблиц вручную при работающей или даже остановленной базе без полного дампа — это прямой путь к потере данных. Освобождайте место только безопасными средствами.
Профилактика: чтобы место не кончалось внезапно
Переполнение диска почти всегда предсказуемо, если следить за ним. Настройте мониторинг свободного места с оповещением на 80–85% заполнения — тогда у вас будет запас времени среагировать, а не аврал с упавшей базой. Задайте автоматическую очистку бинлогов через binlog_expire_logs_seconds, включите ротацию всех логов MySQL, держите general_log выключенным на проде.
Регулярно проверяйте рост крупнейших таблиц и заранее планируйте архивацию истории и логов приложения — это самые быстрорастущие данные. И трезво оценивайте объём диска под проект: если данные честно растут, а места мало, разумнее заранее взять сервер с большим или расширяемым диском, чем каждую неделю бороться за гигабайты. Запас по диску под базу — это не роскошь, а страховка от простоя и повреждения данных.
Полезно также помнить, что бэкапы и дампы, которые вы делаете, тоже занимают место — и нередко именно они добивают диск. Держите резервные копии не на том же разделе, что и рабочая база, а на отдельном хранилище или выгружайте их наружу сразу после создания. Иначе получается замкнутый круг: диск заполнен, а половину его съели старые дампы самой базы. Настройте ротацию бэкапов — храните разумное число последних копий, а старые удаляйте автоматически. Тогда и данные защищены, и место под контролем, и переполнение перестаёт быть регулярной аварией.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США и РФ. Оплата картой РФ и по СБП.
Арендовать VPS под базуОбсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Частые вопросы
Что чаще всего съедает место у MySQL?
Неограниченные бинарные логи — причина номер один. Также раздутый ibdata1, большие таблицы логов и истории, случайно включённый general_log. Найти виновника поможет du -sh /var/lib/mysql/*.
Как удалить бинлоги, не сломав базу?
Только через PURGE BINARY LOGS BEFORE ..., а не командой rm. Ручное удаление файлов ломает индекс логов. Настройте автоочистку через binlog_expire_logs_seconds.
Удалил строки, но место не вернулось. Почему?
InnoDB не отдаёт место на диск автоматически после удаления. Выполните OPTIMIZE TABLE имя;, чтобы физически пересобрать таблицу и освободить пространство.
Как оплатить сервер с большим диском из России?
В MAATRIX — картой российского банка, через СБП, криптовалютой или токеном MAAT. Иностранная карта не нужна.
Нужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.