Как сжать файл innodb ibdata1 без сброса всех баз данных?

24

InnoDB хранит все таблицы в одном большом файле ibdata1.

После удаления большой таблицы файл сохраняет свой размер независимо от размера таблицы. Как можно сжать этот файл без необходимости выгрузки и повторного импорта всей базы данных (всего несколько сотен ГБ)?

Я думаю, что причина в том, что вы все еще можете откатить сброс. В моем случае мне это не нужно.

rubo77
источник

Ответы:

30

Это одна из самых противоречивых тем, с которыми я когда-либо сталкивался на протяжении многих лет как администратор баз данных 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.

RolandoMySQLDBA
источник
1
Незначительная коррекция: MSSQL и PostgreSQL могут откатывать DDL. Oracle не может. На самом деле Oracle выдает неявный коммит, когда видит DDL!
Крис Треверс
1
@RolandoMySQLDBA, поскольку с какой версии MySQL работает эта «хорошая новость» автоматического сжатия?
Гавриил
@ Гавриил - Я думаю, ты неправильно понял. Вы все еще должны сбросить; удалить ibdata1; перезапуск; и перезагрузите. Нет-автоусадка ibdata1. (Менять iblog * теперь проще.)
Рик Джеймс
2

InnoDB хранит все ваши таблицы InnoDB только в ibdata1, если вы не используете следующую настройку в файле по умолчанию my.cnf:

innodb_file_per_table = 1

DROP TABLE (и DROP DATABASE) нельзя откатить.

Это не причина, по которой вы не можете уменьшить ibdata1.

Это сокращенное объяснение, но ibdata1 содержит внутренние компоненты InnoDB в дополнение к данным вашей таблицы. Насколько я понимаю, чтобы уменьшить его, потребуется его дефрагментация, что не поддерживается.

Майкл - sqlbot
источник