Чому росте файл ibdata1
ibdata1 — це системний табличний файл (shared tablespace) InnoDB. У ньому завжди зберігаються службові дані: словник даних, буфер скасування (undo log) і, якщо параметр innodb_file_per_table вимкнений, ще й самі таблиці разом з індексами. Файл лежить у каталозі даних, зазвичай /var/lib/mysql/ibdata1, і ніколи не зменшується сам — лише зростає.
Особливість InnoDB в тому, що навіть видалення рядків або цілих таблиць не повертає місце операційній системі: рушій позначає простір як вільний усередині самого файлу і використовує його повторно для нових даних, але розмір файлу на диску залишається тим самим.
Як перевірити, що саме займає місце
Перш ніж щось видаляти, варто з'ясувати, чи винен ibdata1, чи проблема в окремих файлах таблиць.
du -sh /var/lib/mysql/ibdata1
du -sh /var/lib/mysql/*/ | sort -rh | head -20
SELECT table_schema, ROUND(SUM(data_length+index_length)/1024/1024,1) AS mb
FROM information_schema.tables GROUP BY table_schema ORDER BY mb DESC;Якщо innodb_file_per_table увімкнений (за замовчуванням з версії 5.6), кожна таблиця зберігається у власному файлі .ibd, а в ibdata1 залишаються лише словник і undo-логи — зазвичай це кілька сотень мегабайт, не більше.
Що зберігається в ibdata1, а що — в окремих файлах
| Вміст | Де зберігається при file_per_table=ON | Де зберігається при file_per_table=OFF |
|---|---|---|
| Дані та індекси таблиць | окремий файл ім'я_таблиці.ibd | усередині ibdata1 |
| Словник даних InnoDB | ibdata1 | ibdata1 |
| Undo-логи транзакцій | ibdata1 або окремі undo-файли | ibdata1 |
Як увімкнути file-per-table для нових таблиць
Параметр вмикається в конфігурації і діє лише для таблиць, створених після зміни — старі таблиці всередині ibdata1 він автоматично не чіпає.
# /etc/mysql/my.cnf, секція [mysqld]
innodb_file_per_table = 1Після правки конфігурація перечитується перезапуском сервісу. Детальніше про секції my.cnf і пов'язані параметри — у статті про оптимізацію my.cnf.
Як зменшити вже розрослий ibdata1
Штатної команди стиснення ibdata1 не існує — файл зменшується лише через повне перестворення каталогу даних. Це планова операція із зупинкою сервісу, а не швидкий фікс.
- Зробити повний дамп усіх баз через mysqldump, включно з тригерами, процедурами і подіями.
- Зупинити MySQL і перемістити (не видаляти одразу) весь каталог даних у резервне місце.
- Увімкнути innodb_file_per_table і ініціалізувати новий порожній каталог даних.
- Імпортувати дампи назад — нові таблиці створяться в окремих .ibd файлах.
systemctl stop mysql
mv /var/lib/mysql /var/lib/mysql.old
mysqld --initialize --datadir=/var/lib/mysql
systemctl start mysql
mysql -u root -p < /root/full_backup.sqlПрофілактика: що ще займає місце на диску
ibdata1 — не єдине джерело зростання каталогу даних, і часто плутають кілька причин одразу.
- Тимчасові таблиці для великих GROUP BY і ORDER BY створюються на диску в ibtmp1, який теж не зменшується без перезапуску сервера.
- Бінарні логи реплікації накопичуються без ротації — налаштування їх зберігання описано у статті про binlog і відновлення на точку в часі.
- Фрагментація таблиць після масових DELETE знижується командою OPTIMIZE TABLE, але вона потребує вільного місця, рівного розміру таблиці.
Підсумок: чек-лист щодо місця на диску
- Перевірити розмір ibdata1 і чи увімкнений innodb_file_per_table.
- Знайти реальних споживачів місця через information_schema.tables.
- Для нових таблиць тримати file_per_table увімкненим за замовчуванням.
- Зменшувати ibdata1 лише через повний дамп і перестворення каталогу даних.
- Налаштувати ротацію бінарних логів, щоб вони не росли безконтрольно.