Почему бинарные логи MySQL 8 занимают 19 ГБ при базе 2.5 ГБ
Бинарные логи (binlog) в MySQL 8 - это журналы, которые записывают все изменения данных: INSERT, UPDATE, DELETE, а также изменения структуры таблиц. Они необходимы для репликации и восстановления после сбоев. Однако на сервере Debian с MODX и базой 2.5 ГБ они могут неожиданно разрастись до 19 ГБ. Разберёмся, почему это происходит и как решить проблему.
Основные причины огромного размера binlog
Binlog растут из-за частых операций записи. Даже если база небольшая, активные CMS (например, MODX) могут генерировать тысячи запросов в день: логирование, сессии, кеширование. Каждая такая операция фиксируется в бинарном логе. Дополнительные факторы:
- Формат логирования ROW - в MySQL 8 по умолчанию используется row-based replication, где записывается полная копия каждой изменённой строки, а не только SQL-запрос. Это увеличивает размер лога в 5-10 раз по сравнению со statement-based.
- Долгое время хранения - если в конфиге не задано
expire_logs_daysилиbinlog_expire_logs_seconds, логи хранятся бесконечно и накапливаются. - Транзакции большого объёма - массовые обновления (например, импорт данных или массовая публикация ресурсов в MODX) фиксируются одной транзакцией, что создаёт гигантский файл.
- Отсутствие автоматической очистки - если не настроена ротация, старые логи не удаляются, и суммарный вес растёт.
Как проверить текущее состояние binlog
Выполните в MySQL следующие запросы:
SHOW BINARY LOGS;Эта команда покажет список всех файлов и их размер. Чтобы узнать текущий формат логирования:
SHOW VARIABLES LIKE 'binlog_format';Если значение ROW, это одна из причин большого объёма. Также проверьте настройки хранения:
SHOW VARIABLES LIKE 'binlog_expire_logs_seconds';Как уменьшить размер binlog и настроить очистку
Для решения проблемы настройте следующие параметры в файле /etc/mysql/my.cnf или /etc/my.cnf:
[mysqld]
binlog_expire_logs_seconds = 86400
max_binlog_size = 200Mbinlog_expire_logs_seconds = 86400- логи будут храниться ровно 1 день (24 часа). Для тестового сервера этого достаточно. Для продакшена можно поставить 2592000 (30 дней), но тогда контролируйте объём.max_binlog_size = 200M- каждый файл лога не превысит 200 МБ. MySQL автоматически создаст новый файл при достижении лимита.
После изменения конфига перезапустите MySQL:
systemctl restart mysqlДля немедленной очистки старых логов выполните:
PURGE BINARY LOGS BEFORE NOW();Или удалите логи до определённой даты:
PURGE BINARY LOGS BEFORE '2025-01-01 00:00:00';Дополнительные рекомендации
Если проблема повторяется, рассмотрите:
- Смена формата на MIXED - для баз, где репликация не критична, можно установить
binlog_format = MIXED. Это уменьшит размер, но может нарушить репликацию. - Отключение binlog - если репликация не используется, можно закомментировать
log-binв конфиге. Однако это лишит вас возможности восстановления на момент времени. - Оптимизация запросов MODX - проверьте, не генерирует ли сайт избыточные записи (например, логи ошибок или сессии в БД). Используйте кеширование.
Вывод
Binlog размером 19 ГБ при базе 2.5 ГБ - нормальное явление для MySQL 8 с форматом ROW и отсутствием ротации. Настройте binlog_expire_logs_seconds и max_binlog_size, чтобы автоматически очищать логи. После этого проблема с местом на сервере Debian будет решена.