MySQL InnoDB - минусы innodb_file_per_table?
По умолчанию MySQL InnoDB хранит все таблицы всех БД в одном глобальном файле. Вы можете изменить это, установив innodb_file_per_table в конфигурации, которая затем создает один файл данных для каждой таблицы.
Мне интересно почему innodb_file_per_table
не включен по умолчанию. Есть ли недостатки в его использовании?
6 ответов
У меня есть полный ответ на этот.
После того, как innodb_file_per_table установлен, и новые таблицы InnoDB могут быть сокращены с помощью ALTER TABLE <innodb-table-name> ENGINE=InnoDB';
Это будет сокращать новый .ibd
файлы гарантированы.
Если вы бежите ALTER TABLE <innodb-table-name> ENGINE=InnoDB';
в таблице InnoDB, созданной до того, как вы использовали innodb_file_per_table, она извлечет данные и индексы для этой таблицы из файла ibdata1 и сохранит их в .ibd
file, в ibdata1 останется целое почтового голубя, которое никогда не будет использовано повторно.
ibdata1
файл обычно содержит четыре типа информации
- Данные таблицы
- Табличные индексы
- Данные MVCC (Multiversioning Concurrency Control)
- Откат сегментов
- Отменить пробел
- Метаданные таблицы (словарь данных)
- Double Write Buffer (фоновая запись для предотвращения зависимости от кэширования ОС)
- Вставить буфер (управление изменениями в неуникальных вторичных индексах)
- Увидеть
Pictorial Representation of ibdata1
Вот гарантированный способ сжать файл ibdata1 почти навсегда...
ШАГ 01) MySQLDump все базы данных в текстовый файл SQL (назовите его SQLData.sql)
ШАГ 02) Удалите все базы данных (кроме схем mysql, information_schema и performance_schema)
ШАГ 03) Отключение mysql
ШАГ 04) Добавьте следующие строки в /etc/my.cnf
[mysqld]
innodb_file_per_table
innodb_flush_method=O_DIRECT
innodb_log_file_size=1G
innodb_buffer_pool_size=4G
innodb_data_file_path=ibdata1:10M:autoextend
Замечание. Независимо от того, какой у вас набор для innodb_buffer_pool_size, убедитесь, что innodb_log_file_size составляет 25% от innodb_buffer_pool_size.
- ШАГ 05) Удалите ibdata1, ib_logfile0 и ib_logfile1 (см. Обновление ниже перед удалением!)
На этом этапе должна быть только схема mysql в /var/lib/mysql
- ШАГ 06) Перезапустите MySQL
Это восстановит ibdata1 на 10 МБ (не настраивать опцию), ib_logfile0 и ib_logfile1 на 1G каждый
- ШАГ 07) Перезагрузите SQLData.sql в mysql
ibdata1
будет расти, но будет содержать только метаданные таблицы и прерывистые данные MVCC.
Каждая таблица InnoDB будет существовать вне ibdata1
Предположим, у вас есть таблица InnoDB с именем mydb.mytable. Если вы идете в /var/lib/mysql/mydb
, вы увидите два файла, представляющих таблицу
mytable.frm
(Заголовок механизма хранения)mytable.ibd
(Главная таблицы данных и табличных индексов дляmydb.mytable
)
ibdata1
никогда не будет содержать данные InnoDB и индексы.
С опцией innodb_file_per_table в /etc/my.cnf
, Вы можете запустить OPTIMIZE TABLE mydb.mytable
ИЛИ ЖЕ ALTER TABLE mydb.mytable ENGINE=InnoDB;
и файл /var/lib/mysql/mydb/mytable.ibd
будет на самом деле сжаться.
Я делал это много раз за свою карьеру в качестве администратора баз данных MySQL, не испытывая при этом ни единой проблемы. Фактически, в первый раз, когда я сделал это, я свернул файл ibdata1 размером 50 ГБ в 50 МБ.
Попробуйте. Если у вас есть дополнительные вопросы по этому поводу, напишите мне. Доверьтесь мне. Это будет работать в краткосрочной и долгосрочной перспективе.
ОБНОВЛЕНИЕ 2013-07-02 15:08 ПО ВОСТОЧНОМУ ВРЕМЕНИ
В этом отношении у меня есть оговорка, которую я обновил в других своих постах, но я пропустил это: я обновляю свой ответ немного больше с помощью innodb_fast_shutdown, потому что я использовал для перезапуска mysql и остановки mysql, чтобы сделать это. Теперь этот один шаг жизненно важен, потому что каждая незафиксированная транзакция может иметь другие движущиеся части внутри и за пределами журналов транзакций InnoDB ( см. Инфраструктура InnoDB).
Обратите внимание, что установка innodb_fast_shutdown в 2 также очистит журналы, но больше движущихся частей все еще существует и будет выбрано в Crash Recovery во время запуска mysqld. Установка 0 лучше.
Причина, по которой я решил не использовать innodb_file_per_table
, потому что каждая таблица помещается в свой собственный файл, что означает, что каждая таблица получает свои собственные, отдельные издержки (подписи файлов и т. д.), что вызывает общий, общий размер MySQL
каталог должен быть больше, чем при использовании общего табличного пространства. Кроме того, из-за сбоя в работе кластера больше неиспользуемого пространства при наличии нескольких небольших файлов вместо одного большого файла.
Конечно, дополнительные издержки не являются огромной суммой в общей схеме вещей, особенно если вы используете большой диск или имеете гигантскую базу данных, но для меня (и, вероятно, многих "домашних пользователей") все это складывается и было все еще слишком много для маленького диска с большими кластерами, где я хранил свое хранилище MySQL.
Например, мое хранилище баз данных с моими базами данных WordPress и несколькими другими небольшими базами данных (phpBB, dev, некоторые тесты AMP и т. Д.), Преобразованное в таблицу, изменило его с 32 МБ до 50 МБ, и это даже не включая ibdata1
который по-прежнему требует минимум 10 МБ, в общей сложности не менее 60 МБ.
Как я уже сказал, это может быть не слишком большой проблемой для некоторых людей, особенно для предприятий, но если вы являетесь домашним пользователем, который только размещает ваш сайт, блог и т. Д., То это действительно может быть фактором, влияющим на выбор хост-провайдер, потому что многие хосты ограничивают размер вашей базы данных в дополнение к общему использованию диска.
Просто чтобы добавить немного больше информации
Поскольку mysql 5.6.6 включен по умолчанию
С innodb_file_per_table=1, удаление таблицы может быть медленнее, см. здесь