Кожен адміністратор серверів рано чи пізно стикається з ситуацією, коли на VPS чи виділеному сервері різко зникає вільний простір на диску. Часто це трапляється несподівано: ще вчора на диску залишалося кілька десятків гігабайтів, а сьогодні система починає скаржитися на помилки запису, сервіси зупиняються, а сайти перестають працювати.

Одна з найпоширеніших причин цього на Ubuntu Server – це база даних MySQL/MariaDB, яка створює бінарні журнали (binlogs), або ж надмірне накопичення системних та веб-логів. У цій статті ми розглянемо покроково, як діагностувати проблему, знайти «пожирачів» місця та раз і назавжди вирішити питання з бінарними логами MySQL.

Крок 1. Перевіряємо використання диску

Першим ділом завжди дивимося, який розділ забився. Для цього використовується команда:

df -h

Вона показує усі файлові системи та їхній відсоток заповнення. Найчастіше на веб-серверах переповнюється саме кореневий розділ /.

Щоб зрозуміти, яка папка займає найбільше місця, використовуємо du:

sudo du -h --max-depth=1 / | sort -h

Ця команда дає розбивку по каталогах верхнього рівня. У нашому випадку відразу стало видно, що /var виріс до 19 ГБ, тоді як інші каталоги займали значно менше. Це вже підказка: треба копати в сторону бази даних та логів.

Крок 2. Аналізуємо каталог /var

Каталог /var – це класичне місце, де накопичуються логи, тимчасові файли та бази даних. Для детальної перевірки запускаємо:

sudo du -h --max-depth=1 /var | sort -h

Результат показав, що основними «винуватцями» стали:

Тут уже зрозуміло: база даних та журнали з’їли диск.

Крок 3. Логи системи та веб-сервера

Почнемо з логів. У системі Ubuntu є два основних джерела великих логів:

  1. systemd-journald – зберігає журнали у /var/log/journal/.
  2. Apache/Nginx – доступи та помилки сайтів у /var/log/apache2/ чи /var/log/nginx/.

Перевірка журналів systemd:

sudo journalctl --disk-usage

У нашому випадку journald займав 1,6 ГБ. Це не критично, але й не мало.

Щоб скоротити ці логи, є два варіанти:

sudo journalctl --vacuum-time=7d
sudo journalctl --vacuum-size=200M

Очищення логів Apache/Nginx

Якщо у вас активний трафік, логи можуть виростати на сотні мегабайт за кілька місяців. Їх можна «обнулити» без видалення файлів:

sudo truncate -s 0 /var/log/apache2/*.log

Аналогічно для Nginx:

sudo truncate -s 0 /var/log/nginx/*.log

Звісно, для регулярного обслуговування краще налаштувати logrotate, але в екстреній ситуації це швидкий спосіб.

Крок 4. Найбільший винуватець – MySQL binlogs

Коли ми розгорнули каталог /var/lib/mysql, виявилося, що найбільше місця займали файли формату binlog.0000xx. Вони створюються MySQL автоматично, навіть якщо ви не використовуєте реплікацію.

Що таке binlogs?

Бінарні журнали (binlogs) – це історія всіх змін у базі даних. Вони потрібні для відновлення після збоїв та для реплікації на інші сервери. Проблема у тому, що за замовчуванням MySQL може накопичувати їх без обмежень, якщо не вказати термін життя.

У нашому випадку binlogs зайняли понад 12 ГБ.

Крок 5. Як безпечно очистити binlogs

Найкраще не видаляти їх руками, а використовувати команди MySQL.

  1. Заходимо в MySQL:
sudo mysql -uroot -p
  1. Дивимось наявні журнали:
SHOW BINARY LOGS;
  1. Якщо реплікація не використовується – можна очистити все:
RESET MASTER;

Або ж залишити журнали лише за останній тиждень:

PURGE BINARY LOGS BEFORE DATE(NOW()) - INTERVAL 7 DAY;

Після цього вільного місця одразу стане значно більше.

Крок 6. Як відключити binlogs назавжди

Якщо ви не використовуєте реплікацію і вам не потрібні журнали транзакцій – найкраще вимкнути їх повністю.

Для цього відкриваємо файл конфігурації:

sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf

Або, якщо стоїть MariaDB:

sudo nano /etc/mysql/mariadb.conf.d/50-server.cnf

І в секції [mysqld] додаємо рядок:

skip-log-bin

Після цього перезапускаємо MySQL:

sudo systemctl restart mysql

Перевіряємо:

mysql -e "SHOW VARIABLES LIKE 'log_bin';"

Результат має бути OFF.

Тепер binlogs більше не створюватимуться, і проблема з неконтрольним розростанням зникне.

Крок 7. Якщо binlogs все ж потрібні

Є сценарії, коли binlogs потрібні – наприклад, якщо ви налаштовуєте реплікацію чи використовуєте точкове відновлення. У такому випадку вимикати їх не варто. Замість цього треба задати обмеження часу зберігання.

У конфіг додаємо:

max_binlog_size           = 100M
binlog_expire_logs_seconds = 604800   # 7 днів

Після перезапуску MySQL він автоматично видалятиме старі журнали, а диск не заповнюватиметься.

Крок 8. Інші способи звільнити місце

Окрім бази даних і логів, на сервері ще є кілька стандартних місць, де може накопичуватись сміття:

sudo apt-get clean
sudo rm -rf /tmp/*
sudo apt-get autoremove --purge

Також дуже зручно встановити інструмент ncdu:

sudo apt install ncdu -y
sudo ncdu /

Він дозволяє в інтерактивному режимі подивитися, які папки займають найбільше місця, і одразу видалити непотрібне.

Висновок

Закінчення місця на сервері – це завжди стресова ситуація, але вирішується вона доволі швидко, якщо знати, куди дивитися. У більшості випадків основними причинами є:

Щоб уникнути проблеми у майбутньому:

Таким чином ви зможете підтримувати сервер у стабільному стані, уникнути простою сайтів і заощадити час у кризових ситуаціях.