Табличний простір innodb

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

Конфігурація табличного простору Файли, що поміщаються в табличний простір, перераховуються в конфігураційному параметрі innodb_data_file_path. Всі вони будуть знаходитися в каталозі, який задається параметром innodb_data_home_dir. наприклад:

innoCb_Cata_home_Cir = / var / lib / mysql / innoCb_Cata_file_path = ibCata1: 1G; ibdata2: 1G; ibdata3: 1G

В результаті створюється табличний простір розміром 3 Гбайт, що містить три файли. Іноді задають питання, чи можна використовувати кілька файлів для розподілу навантаження на кілька накопичувачів, наприклад так:

При цьому файли дійсно поміщаються в різні каталоги, які в даному випадку знаходяться на різних дисках, але InnoDB конкатенуються файли один за одним. Тому в даному випадку ніякого реального виграшу ви не отримаєте. InnoDB спочатку буде писати в перший файл, потім, коли він заповниться, - у другій і т. Д. Тобто навантаження не розподіляється так, як хотілося б для забезпечення високої продуктивності. Для цієї мети краще використовувати RAID-контролер.

Щоб табличний простір могло рости, коли місце закінчується, можна зробити останній файл автоматично розширюваним:

За замовчуванням створюється один автоматично розширюваний файл розміром 10 Мбайт. Якщо ви вирішите зробити файл автоматично розширюваним, то має сенс обмежити розмір табличного простору зверху, оскільки, досягнувши певного розміру, файл вже не ущільнюється (does not shrink). Наприклад, в наступному прикладі розмір автоматично розширюється файлу обмежений 2 Гбайт:

Параметр innodb_file_per_table дозволяє настроїти InnoDB з одним файлом на таблицю (починаючи з версії MySQL 4.1). Дані зберігаються в каталозі бази даних в файлах з іменами виду tablename.ibd. Так простіше звільняти місце при видаленні таблиці, до того ж цей режим корисний для розподілу таблиць по різних дисках. Однак в разі зберігання даних в декількох файлах більше місця витрачається даремно, оскільки ви обмінюєте внутрішню фрагментацію в одному табличному просторі на неиспользуемое місце в IBD-файлах. Ця проблема більше стосується маленьких таблиць, так як розмір сторінки в InnoDB становить 16 Кбайт. Навіть якщо в таблиці зберігається всього 1 Кбайт даних, на диску вона все одно буде займати 16 Кбайт.

Слід також зазначити, що файли InnoDB необов'язково зберігати в традиційній файлової системи. Як і багато інших СУБД, InnoDB дозволяє розміщувати їх на Неформатована (raw) розділі диска. Однак сучасні файлові системи вміють ефективно працювати з досить великими об'єктами, тому в такому режимі немає особливого сенсу. Використання неформатованих пристроїв може дати приріст продуктивності на кілька відсотків, але ми не вважаємо, що такий мізерний виграш виправдовує незручності, пов'язані з неможливістю маніпулювати даними, як файлами. Якщо вони знаходяться на Неформатована пристрої, то серед команд вищої mv, cp і інших можна забути. Ми також вважаємо, що кошти зняття миттєвих знімків, наприклад ті, що пропонує менеджер логічних томів (LVM) в системі GNU / Linux, - це колосальне зручність. Ви, звичайно, можете помістити неформатований пристрій на логічний тому, але при цьому обессмислівается сама ідея - такий накопичувач вже не є неформатований. Загалом, через те крихітного виграшу, який дають неформатовані пристрої, не варто затівати метушню.

Більш ранні версії рядків і табличний простір В умовах інтенсивної записи табличний простір InnoDB може стати дуже великим. Якщо транзакція довгий час залишається відкритою (навіть не роблячи нічого корисного) і при цьому встановлений рівень ізоляції REPEATABLE READ, то InnoDB не може видалити старі версії рядків, оскільки вони повинні бути видні незафіксованим транзакціях. InnoDB зберігає старі версії в табличному просторі, тому воно продовжує рости по мірі відновлення даних. Іноді проблема пов'язана не з відкритими транзакціями, а просто з характером робочого навантаження: чищенням займається тільки один потік, він може просто не встигати видаляти старі версії рядків.

У будь-якому випадку команда SHOW INNODB STATUS допоможе ідентифікувати причину проблеми. Погляньте на першу і другу рядки в секції TRANSACTIONS, там показаний поточний номер транзакції і точка, до якої дійшла чистка. Якщо різниця велика, значить, накопичилося багато невичіщенних транзакцій. наприклад:

Trx id counter 0 80157601

Purge done for trx's n: o <0 80154573 undo n:o <0 0

Ідентифікатор транзакції - це 64-розрядне число, складене з двох 32-розрядних, тому для обчислення різниці доведеться трохи помучитися. В даному випадку все просто, так як старші розряди рівні 0, отже, ми маємо 80157601 - 80154573 = 3028 потенційно невичіщенних транзакцій (утиліта innotop виконає за вас все обчислення). Ми говоримо «потенційно», оскільки велика різниця ще не означає, що є багато невичіщенних рядків. Більш ранні версії рядків створюються тільки для транзакцій, які змінюють дані, а може існувати безліч транзакцій, в яких дано ні не змінювалися (і навпаки - одна транзакція може змінити багато рядків).

Якщо є багато невичіщенних транзакцій і з цієї причини табличний простір продовжує зростати, то можна примусово уповільнити роботу MySQL, щоб потік очищення InnoDB встигав справлятися з навантаженням. Звучить не дуже привабливо, але альтернативи немає. В іншому випадку InnoDB буде продовжувати писати дані і заповнювати диск, поки на ньому не скінчиться місце або не буде досягнута задана верхня межа розміру табличного простору.

Щоб «пригальмувати» запис, надайте змінної innodb_max_purge_ lag значення, відмінне від 0. Воно дорівнює максимальній кількості транзакцій, які очікують очищення; після досягнення цього порогу InnoDB починає затримувати виконання запитів на оновлення даних. Щоб вибрати відповідне значення, потрібно знати конкретну робоче навантаження. Наприклад, якщо типова транзакція змінює в середньому 1 Кбайт даних і ви готові змиритися зі 100 Мбайт «невичіщенних» рядків в табличному просторі, то можете задати значення 100000.

Майте на увазі, що наявність невичіщенних версій рядків відбивається на всіх запитах, оскільки через них збільшується розмір таблиць і індексів. Якщо потік очищення не справляється з навантаженням, то продуктивність може помітно впасти. Завдання параметра innodb_max_ purge_lag теж знижує швидкість виконання запитів, але це менше з двох зол.