Почему растёт файл 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 только через полный дамп и пересоздание каталога данных.
- Настроить ротацию бинарных логов, чтобы они не росли бесконтрольно.