Зачем использовать innodb_file_per_table?


27

Есть много статей, преувеличивающих (ИМХО конечно) необходимость innodb_file_per_table. Я понимаю, что с innodb_file_per_tableэтим должен быть лучший контроль над отдельными таблицами; как резервное копирование каждой таблицы в отдельности. Однако претензия на лучшую производительность сомнительна.

В моем тесте нет разницы в производительности innodb_file_per_tableи ibdata1для базы данных объемом 60 ГБ. Конечно, это был простой тест с обычными запросами, и ситуация для сложных запросов в реальной жизни может быть иной (именно поэтому я и задал этот вопрос). 64-разрядная версия Linux ext4может эффективно обрабатывать большие файлы.

При innodb_file_per_tableэтом требуется больше операций дискового ввода-вывода; и это важно в сложных JOINи FOREIGN KEYограничениях.

Табличное пространство используется совместно ibdata; Как выделенные табличные пространства для отдельных таблиц могут сэкономить дисковое пространство? Конечно, проще освободить табличное пространство для каждой таблицы ALTER, но это все еще дорогой процесс (с блокировкой таблицы).

ВОПРОС: Влияет ли innodb_file_per_tableэто на лучшую производительность mysql? Если да, то почему?


Посмотрите ответ на мой вопрос: dba.stackexchange.com/questions/7924/… может также помочь.
КМ.

Ответы:


19

Я не думаю, что это вопрос производительности, а управления.

Имея отдельный файл на таблицу, вы можете хранить разные базы данных на разных устройствах хранения, например.

Вы можете иметь дело со случаями очень больших баз данных в файловых системах, которые не могут обрабатывать большие файлы (по крайней мере отложить проблему до тех пор, пока одна таблица не достигнет предела размера файла).

У вас нет неконтролируемого роста табличного пространства. Если у вас есть несколько больших таблиц, которые вы отбрасываете, ibdataфайл остается маленьким.

Одним из аспектов, который может оказать некоторое влияние на производительность, является фрагментация данных таблицы и индексов, которая будет ограничена для каждой таблицы. Но это требует тестирования, чтобы быть подтвержденным.


Рост табличного пространства - именно то, чего вы хотите innodb_file_per_table.
sjas

13

Зачем использовать innodb_file_per_table?

Потому что легче управлять человеком, так как это можно сделать на уровне файлов. Это означает, что даже если сервер не работает, вы все равно можете копировать данные, копируя файлы таблиц, тогда как использование общего табличного пространства означает либо копирование всего, что может быть излишне массивным, либо поиск какого-либо способа заставить сервер работать для извлечения данных ( Вы действительно не хотите извлекать данные вручную с помощью hex-редактора).

Кто-то предупредил, что нельзя просто копировать и вставлять .ibdфайлы с одного сервера на другой. Это может быть правдой, но это не должно применяться к резервным копиям на том же сервере (здесь я использую термин « резервное копирование» в традиционном смысле создания копии; т. Е. Не радикально изменяя все это). Более того, ibdata1он автоматически воссоздается при запуске (как видно на этапе удаленияibdata1 большинства руководств по «преобразованию в файл на таблицу»). Таким образом, вам не нужно копировать ibdata1в дополнение к вашим .ibdфайлам (и их соответствующие .frm, и т. Д. Файлы).

Если вы пытаетесь восстановить потерянную таблицу, ее должно быть достаточно, чтобы скопировать ее .ibdи .frmфайл, а также information_schema(что намного меньше, чем ibdata1). Таким образом, вы можете поместить их на фиктивный сервер и извлечь свою таблицу, не копируя всю массивную информацию.

Однако претензия на лучшую производительность сомнительна. … С помощью innodb_file_per_table требуется больше операций дискового ввода-вывода; и это важно для сложных соединений и ограничений FOREIGN KEY.

Неудивительно, что производительность будет полностью зависеть от конкретной используемой базы данных. Один человек будет иметь (даже очень) разные результаты от другого.

Это правда, что будет больше операций дискового ввода-вывода с файлом на таблицу, но только немного больше. Подумайте, как работает система.

  • Для монолитной базы данных:

    1. Сервер запущен
    2. ibdata1 открыт
    3. Заголовок и метаданные читаются
    4. Структуры и метаданные кэшируются в памяти
    5. Запросы случаются
      1. Сервер получает доступ к диску и считывает данные с уже открытого ibdata1
      2. Сервер может кэшировать данные в памяти
  • Для базы данных на таблицу:

    1. Сервер запущен
    2. ibdata1 открыт
    3. Заголовок и метаданные читаются
    4. Каждый отдельный .ibdфайл открывается
    5. Заголовок и метаданные читаются из каждого .ibdфайла
    6. Структуры и метаданные кэшируются в памяти
    7. Запросы случаются
      1. Сервер обращается к диску и читает данные из уже открытого .ibdфайла
      2. Сервер может кэшировать данные в памяти

Вы заметите, что когда сервер работает, вы не можете перемещать файлы данных, потому что у сервера есть открытые дескрипторы к ним. Это потому, что когда он запускается, он открывает их и оставляет их открытыми. Он не открывает и не закрывает их для каждого отдельного запроса.

Таким образом, есть только несколько операций ввода-вывода в начале, когда сервер запускается; нет, пока он работает. Кроме того, хотя каждый отдельный .ibdфайл имеет свои отдельные служебные данные (подписи файлов, структуры и т. Д.), Они кэшируются в памяти и не перечитываются для каждого запроса. Более того, одни и те же структуры читаются даже с общим табличным пространством, поэтому требуется чуть больше (если вообще вообще имеется) больше памяти.

Влияет ли innodb_file_per_table на лучшую производительность mysql?

На самом деле, если что - нибудь, производительность на самом деле может быть хуже .

При использовании общего табличного пространства операции чтения и записи могут иногда / часто комбинироваться так, чтобы сервер считывал набор данных из нескольких таблиц за один раз ibdata.

Однако если данные распределены по нескольким файлам, то для каждого из них необходимо выполнить отдельную операцию ввода-вывода.

Конечно, это снова полностью зависит от рассматриваемой базы данных; реальное влияние на производительность будет зависеть от размера, частоты запросов и внутренней фрагментации общего табличного пространства. Некоторые люди могут заметить большую разницу, в то время как другие могут вообще не видеть никакого воздействия.

Табличное пространство используется совместно для одной ибдаты; Как выделенные табличные пространства для отдельных таблиц могут сэкономить дисковое пространство?

Это не. Во всяком случае, это увеличивает использование диска.

У меня нет базы данных объемом 60 ГБ для тестирования, но моя «ничтожная» личная база данных, которая содержит мою установку WordPress и несколько небольших таблиц для личного использования и тестирования разработки, весила ~ 30 МБ при использовании общего табличного пространства. После преобразования в файл на таблицу, он разросся до ~ 85 МБ. Даже если отбросить все и повторно импортировать, оно все равно> 60 МБ.

Это увеличение связано с двумя факторами:

  • Абсолютный минимум размер ibdata1есть, по какой - то причине-10MB, даже если у вас нет ничего , но information_schemaв нем хранятся.

  • В совместно используемом табличном пространстве только ibdata1накладные расходы, такие как подписи файлов, метаданные и т. Д., Но в каждой таблице каждый отдельный .ibdфайл имеет все это. Это означает, что общий объем (даже при гипотетическом <10 МБ ibdata1) будет несколько больше по крайней мере:

    GetTotalSizeofOverhead() * GetNumTables()

Очевидно, что это не приведет к значительному увеличению (если вы не используете хост, который ограничивает размер вашей базы данных или хранит их на флэш-накопителе и т. Д.), Но, тем не менее, они увеличиваются, и в то же время путем переключения ( каждой ) таблицы в файл - за столом вы можете уменьшить ibdata1его до 10 МБ, общий объем всегда будет больше, чем был.


11

Это моя причина ВСЕГДА использовать innodb_file_per_table:

Без файла на таблицу файл ibdata никогда не сжимается, не сжимается и не уменьшается в пространстве. Не тогда, когда вы удаляете строку, удаляете таблицу или базу данных. 2 ГБ данных могут мгновенно стать файлом 20 ГБ, если у вас есть активная система очередей.

Допустим, вы хотите сделать резервную копию вашей текущей таблицы 1 ГБ перед изменением, а затем сбросить ее. Вы застряли с ГБ теперь неиспользуемого пространства в ваших ибдатах. Облом.

Вероятно, есть бесконечные примеры случаев, когда временные меры надувают один файл данных, но достаточно сказать, что, по моему мнению, нет причин НЕ использовать innodb_file_per_table

Кроме того, вот хороший пост для чтения: http://code.openark.org/blog/mysql/reasons-to-use-innodb_file_per_table


1
Я понял, что хорошо ВСЕГДА делать это. Магнитные массивы хранения, поддерживаемые твердотельными накопителями, могут более эффективно обрабатывать кэши чтения / записи по сравнению с небольшими файлами для таблиц. Для группы таблиц, которые в 99,99% времени просто «читаются», но не записываются, они всегда находятся в кеше контроллера хранилища, что значительно сокращает время отклика.
sdkks

5

Моя причина, почему не использовать innodb_file_per_table - это производительность.

Я провел несколько тестов для нашей базы данных с 450 таблицами в mysql 5.5.45 Linux CentOS выпуск 6.7

Для модульных тестов, которые вставляют данные в базу данных перед каждым тестом (не используя все таблицы каждый раз), а также сами тесты много работают с базой данных (вставляет, обновляет, удаляет, выбирает), производительность была в 3-5 раз лучше, когда таблицы базы данных не были разделены на несколько файлов.

Я рекомендую проверить вашу базу данных с запросами, которые вы хотите использовать, и сравнить ее, прежде чем вы решите использовать innodb_file_per_table

Может быть, вы обнаружите, что для производственного сервера вы можете использовать innodb_file_per_table, но для среды CI (продолжает интеграцию), которая запускает модульные тесты (часто использует БД), а также для разработчиков, которые часто запускают модульные тесты, лучше не использовать его из-за производительности.


2
Я предполагаю, что это из-за времени, необходимого для выделения начальных файлов для всех 450 таблиц по сравнению с выделением одного файла. В производстве это произойдет только один раз, поэтому это не должно быть проблемой, но вы должны подчеркнуть, что лучше быстро создать базу данных, а затем полностью ее разорвать и повторять снова и снова один файл ibdata.
ColinM

2

Это делает данные более управляемыми, потому что вы можете освободить неиспользуемое пространство, что приятно.

Я думаю, что если ваша база данных используется в основном для выборочных запросов, это не сильно повлияет на производительность. Он все еще должен прочитать о том же количестве данных. Я не думаю, что это имеет большое значение, из каких файлов он читает данные.

Однако это может ухудшить производительность базы данных, которая выполняет много операций вставки и обновления. Это связано с тем, что mysql вызывает fsync () для файла хранилища после совершения транзакции. Если существует один файл, он делает один вызов и ожидает его завершения. Если имеется много файлов, он должен выполнить вызов несколько раз и дождаться возврата всех этих вызовов, прежде чем команда commit сможет вернуться.

Вот сообщение от кого-то, кто столкнулся с этой проблемой: http://umangg.blogspot.com/2010/02/innodbfilepertable.html


2

Как показано в следующей статье, производительность заключается не в управлении данными (самими операциями типа crud), а в создании и удалении объектов.

innodb_file_per_table делает массовое создание и удаление объектов медленнее, чем хранилище ibdata, и для производства неприменимо, но для непрерывного тестирования должно быть актуально

https://www.percona.com/blog/2015/02/24/mysqls-innodb_file_per_table-slowing/


1

ИМХО лучше использовать innodb_file_per_table, это более безопасно. Если вы не используете его, у вас могут возникнуть проблемы в системах FAT32, где разрешен только 4 ГБ файл. Я написал статью об этом на словацком языке ( https://www.itsoft.sk/preco-sa-neuvolni-miesto-na-disku-po-zmazani-mysql-tabulky/ ).

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.