Навіщо використовувати innodb_file_per_table?


27

Є багато статей, що перебільшують (IMHO, звичайно), необхідність innodb_file_per_table. Я розумію, що з innodb_file_per_table, повинен бути кращий контроль над окремими таблицями; як резервне копіювання кожної таблиці окремо. Однак претензія на кращі показники роботи сумнівна.

У моєму тесті немає різниці в продуктивності innodb_file_per_tableта ibdata1для бази даних 60 Гб. Звичайно, це був простий тест із звичайними запитами, і ситуація може бути різною для складних запитів у реальному житті (це причина, що я задав це запитання). 64-розрядний Linux ext4може ефективно працювати з великими файлами.

З цим потрібно innodb_file_per_tableбільше операцій вводу / виводу диска; і це є важливим у складних JOINs та 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?

Тому що легше керувати особами, оскільки це можна зробити на рівні файлів. Це означає, що навіть якщо сервер не працює, ви все одно можете скопіювати дані, скопіювавши файли таблиць, тоді як використання спільного простору таблиць означає або копіювати все, що може бути непотрібним, або знайти спосіб запустити сервер для отримання даних ( ви дійсно не хочете вручну витягувати дані за допомогою шестигранного редактора).

Хтось попередив, що ви не можете просто копіювати та вставляти .ibdфайли з одного сервера на інший. Це може бути правдою, але це не повинно поширюватися на резервні копії на одному сервері (я тут використовую термін резервне копіювання в традиційному розумінні, щоб зробити копію; тобто не кардинально змінювати всю справу). Більше того, ibdata1він автоматично відтворюється при запуску (як видно на етапі видаленняibdata1 більшості посібників "перетворення файлів на таблицю"). Таким чином, вам не потрібно копіювати ibdata1додатково свої .ibdфайли (та їх відповідні .frmтощо файли).

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

Однак претензія на кращі показники роботи сумнівна. … Із innodb_file_per_table потрібно більше операцій вводу / виводу диска; і це важливо при складних обмеженнях JOIN і 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
Я зрозумів, що це добре ЗАВЖДИ робити це також. Магнітні масиви зберігання, підкріплені SSD, можуть ефективніше кешувати кеші читання / запису щодо менших файлів для таблиць. Для групи таблиць, які% 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 () у файл зберігання після здійснення транзакції. Якщо є один файл, він робить один дзвінок і чекає завершення дзвінка. Якщо є багато файлів, потрібно здійснити виклик кілька разів і чекати, поки всі ці виклики повернуться, перш ніж команда фіксації може повернутися.

Ось допис від того, хто стикався з цією проблемою: http://umangg.blogspot.com/2010/02/innodbfilepertable.html


2

Відповідно до статті нижче, продуктивність стосується не управління даними (грубі операції), а створення та видалення об'єктів.

innodb_file_per_table робить масове створення та видалення об'єктів повільніше, ніж зберігання ibdata, і для виробництва не застосовується, але для постійних тестів має бути актуально.

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


1

IMHO краще використовувати 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.