Senior: питання на співбесіді з теми «Міграції»
Питання з реальних співбесід з відповідями: Laravel і PHP, бази даних, JavaScript і фронтенд, Git, Docker, API, безпека й архітектура. Тими самими темами, що й тести.
2 питання
Міграції виконуються один раз на базу, а не на кожному сервері.
Як цього досягти:
- окремий крок деплою (job у CI, init-контейнер, release-фаза) замість
migrateу старті кожного контейнера; - якщо запускають з кожного сервера -
php artisan migrate --isolated --force: перший бере атомарне блокування в кеші, інші тихо завершуються. Кеш має бути спільним; --forceпотрібен, щоб команда не питала підтвердження на продакшені.
Сумісність схеми й коду. Під час rolling-деплою одночасно працюють стара й нова версії коду, тож міграція має підходити обом:
- Розширення: додати нову колонку (nullable чи з дефолтом), код пише в обидві.
- Перенесення даних фоново порціями.
- Перемикання коду на нову колонку.
- Звуження: видалити стару колонку окремим наступним релізом.
Що ще враховують:
- довгі блокування на великих таблицях:
instant()на MySQL,online()для індексів на PostgreSQL, нічні вікна для важкого; - PostgreSQL обгортає міграцію в транзакцію, а
CREATE INDEX CONCURRENTLYу транзакції не працює; - сідери довідників - окремо від міграцій і ідемпотентні.
Сотні файлів сповільнюють створення бази для тестів і CI, а історія давно не потрібна покроково.
php artisan schema:dump --prune
Команда записує поточну схему в database/schema/{connection}-schema.sql і з --prune видаляє наявні міграції. Нова база спершу виконує SQL зі схеми, а потім - міграції, створені після дампу.
На що зважати:
- Різні СУБД. Дамп робиться для конкретного підключення. Якщо тести йдуть на іншій базі (SQLite замість PostgreSQL), потрібен дамп і для неї - інакше тести не зберуть схему.
- Інструменти. Для дампу потрібні
mysqldumpчиpg_dumpна машині, де виконується команда. - Наявні середовища не зачіпаються: продакшен уже має всі ці міграції в таблиці
migrations. - Дані в міграціях. Якщо старі міграції наповнювали довідники, після стискання цих даних у новій базі не буде - їх переносять у сідери.
Альтернатива без стискання - тримати міграції, але прискорити тести: RefreshDatabase мігрує базу один раз на прогін і далі працює транзакціями, тож кількість міграцій впливає лише на старт.