Чим принципово відрізняються InnoDB і MyISAM
На сервері MySQL і MariaDB кожна таблиця зберігається та обробляється через рушій зберігання — модуль, який визначає формат файлів на диску, підтримку транзакцій і поведінку під час блокувань. З версії MySQL 5.5 рушієм за замовчуванням став InnoDB, але у старих проєктах і в окремих схемах досі трапляється MyISAM. Різниця між InnoDB і MyISAM не косметична: від вибору рушія залежить, чи переживе таблиця аварійний перезапуск сервера без втрати та пошкодження даних.
| Параметр | InnoDB | MyISAM |
|---|---|---|
| Транзакції | Є, ACID | Немає |
| Блокування під час запису | На рівні рядка | На рівні таблиці |
| Зовнішні ключі | Підтримуються | Не підтримуються |
| Повнотекстовий індекс | З версії 5.6 | Підтримується спочатку |
| Відновлення після збою | Автоматичне, за журналом | Часто потрібен REPAIR TABLE |
| Рушій за замовчуванням | Так, з MySQL 5.5 | Ні |
Транзакції та блокування на рівні рядків
InnoDB записує зміни у журнал транзакцій і вміє відкатувати (ROLLBACK) незавершену операцію. Це важливо для інтернет-магазину: якщо платіж перервався посередині запису замовлення, InnoDB відкотить усі пов'язані вставки, а не залишить замовлення у половинчастому стані. MyISAM транзакцій не знає взагалі — будь-яка операція одразу фіксується на диску.
Друга відмінність — гранулярність блокувань. MyISAM блокує всю таблицю на час запису, тому паралельні SELECT чекають у черзі. InnoDB блокує лише ті рядки, які реально змінює запит, і паралельні читачі та автори майже не заважають один одному завдяки MVCC.
Що відбувається при аварійному завершенні сервера
При відключенні живлення або kill -9 процесу mysqld таблиці InnoDB відновлюються автоматично при наступному старті: сервер читає redo-журнал і доводить незафіксовані транзакції до кінця. Адміністратору зазвичай не потрібно робити нічого руками.
З MyISAM усе інакше: файл таблиці може залишитися у пошкодженому стані, і сервер відмовиться з ним працювати, поки не виконати REPAIR TABLE або myisamchk. На великих таблицях відновлення триває годинами, а частина рядків у гіршому разі втрачається безповоротно. Детальніше про резервні копії, які страхують від такої ситуації, дивіться у статті про резервне копіювання mysqldump.
Коли MyISAM ще виправданий
Попри вік рушія, у нього залишаються вузькі сценарії застосування:
- Таблиці лише для читання — архіви логів, довідники, які не змінюються після завантаження.
- Повнотекстовий пошук на старих версіях MySQL без вбудованої підтримки FULLTEXT в InnoDB.
- Імпорт разових вивантажень, де важлива швидкість масової вставки, а цілісність перевіряється окремо.
- Legacy-код старих CMS, який жорстко розрахований на поведінку MyISAM і його не планують переписувати.
Як дізнатися, який рушій використовує таблиця
Найшвидше подивитися рушій через SHOW TABLE STATUS або через information_schema:
SHOW TABLE STATUS FROM shop LIKE 'orders'\G
SELECT table_name, engine FROM information_schema.tables WHERE table_schema='shop';Якщо у виводі поле Engine показує MyISAM для таблиці, де очікуються транзакції, це привід для міграції. Заразом перевірте типи індексів — стаття про оптимізацію індексів MySQL пояснює, як індекси поводяться по-різному на InnoDB та MyISAM.
Як перевести таблицю з MyISAM на InnoDB
Перед конвертацією збережіть резервну копію, потім виконайте зміну рушія однією командою:
ALTER TABLE shop.orders ENGINE=InnoDB;На таблицях у кілька гігабайтів операція блокує запис на час перебудови і може тривати десятки хвилин. Для продакшену без простою використовуйте pt-online-schema-change з набору Percona Toolkit — він копіює дані у фоні та підмінює таблицю атомарно. Після конвертації перевірте параметри буферного пулу InnoDB у конфігу — їм присвячена окрема стаття про налаштування my.cnf.
Підсумок: що обрати для своїх таблиць
Для переважної більшості нових проєктів правильний вибір — InnoDB, і MySQL 8.0 використовує його за замовчуванням без додаткових налаштувань. Перш ніж залишити MyISAM у старій схемі, пройдіться чек-листом:
- Чи потрібні таблиці транзакції або зовнішні ключі — тоді лише InnoDB.
- Чи важлива стійкість до аварійного перезапуску сервера без ручного відновлення.
- Чи є паралельний запис з кількох з'єднань одночасно.
- Чи справді таблиця статична і змінюється не частіше разу на добу.
- Чи перевірена резервна копія перед будь-якою міграцією рушія.