Это одна из самых противоречивых тем, с которыми я когда-либо сталкивался на протяжении многих лет как администратор баз данных MySQL и администратор баз данных StackExchange.
Мягко говоря, просто нет другого способа уменьшить ibdata1 . Когда innodb_file_per_table отключен, при каждом запуске OPTIMIZE TABLE
таблицы InnoDB ibdata1 быстро увеличивается. Данные, которые отбрасываются с использованием DROP TABLE
и DROP DATABASE
не могут быть откатаны, потому что они являются DDL, а не DML. Я считаю, что Oracle и MSSQL могут откатить DDL. MySQL не может этого сделать.
Есть несколько классов информации, которые находятся в ibdata1
- Данные таблицы
- Табличные индексы
- Метаданные таблицы
- Контрольные данные MVCC
- Двойной буфер записи (фоновая запись для предотвращения зависимости от кэширования ОС)
- Вставить буфер (управление изменениями в неуникальных вторичных индексах)
Использование innodb_file_per_table=1
позволит вам создавать новые таблицы с табличными данными и табличными индексами, создаваемыми вне ibdata1. Вы можете извлечь любые таблицы, все еще находящиеся внутри ibdata1, используя ALTER TABLE ... ENGINE=InnoDB;
или, OPTIMIZE TABLE
но это оставит этот большой неиспользуемый пробел в ibdata1.
Несмотря на это, вы должны очистить инфраструктуру InnoDB. Я уже писал в StackExchange сообщения о том, как и зачем это делать:
Хорошие новости
Вам нужно только сбросить данные, перезагрузить еще раз и никогда больше не возвращаться к этой проблеме . Запуск OPTIMIZE TABLE
после этого действительно уменьшит .ibd
файл табличного пространства для любой таблицы InnoDB.
InnoDB хранит все ваши таблицы InnoDB только в ibdata1, если вы не используете следующую настройку в файле по умолчанию my.cnf:
DROP TABLE (и DROP DATABASE) нельзя откатить.
Это не причина, по которой вы не можете уменьшить ibdata1.
Это сокращенное объяснение, но ibdata1 содержит внутренние компоненты InnoDB в дополнение к данным вашей таблицы. Насколько я понимаю, чтобы уменьшить его, потребуется его дефрагментация, что не поддерживается.
источник