Миграции базы данных
Миграции базы данных
Проект использует golang-migrate для управления схемой базы данных состояний (StateStorage).
Обзор
Миграции применяются автоматически при старте приложения (если auto_migrate: true) или могут быть применены вручную. Все миграции находятся в папке migrations/ и следуют стандартному формату golang-migrate.
Формат миграций
Миграции используют формат:
000001_<name>.up.sql— применение миграции000001_<name>.down.sql— откат миграции
Текущие миграции
- 000001_create_worker_progress — создание таблицы
worker_progress - 000002_create_meta_learning_state — создание таблицы
meta_learning_state
Автоматическое применение
При включенном auto_migrate: true в конфигурации StateStorage:
state_storage:
auto_migrate: true # Миграции применяются автоматически при старте
Миграции применяются автоматически при инициализации StateStorage:
stateStorage, err := storage.NewStateStorage(ctx, log, &cfg.StateStorage)
// Миграции применяются автоматически
Ручное управление миграциями
Установка golang-migrate
# macOS
brew install golang-migrate
# Linux
curl -L https://github.com/golang-migrate/migrate/releases/download/v4.19.0/migrate.linux-amd64.tar.gz | tar xvz
sudo mv migrate /usr/local/bin/migrate
# Windows
choco install golang-migrate
Применение миграций
# Применить все миграции
migrate -path migrations \
-database "postgres://user:password@localhost:5432/ml_states?sslmode=disable" \
up
# Применить N миграций
migrate -path migrations \
-database "postgres://user:password@localhost:5432/ml_states?sslmode=disable" \
up N
# Откатить последнюю миграцию
migrate -path migrations \
-database "postgres://user:password@localhost:5432/ml_states?sslmode=disable" \
down 1
# Откатить все миграции
migrate -path migrations \
-database "postgres://user:password@localhost:5432/ml_states?sslmode=disable" \
down -all
Проверка версии
# Текущая версия миграций
migrate -path migrations \
-database "postgres://user:password@localhost:5432/ml_states?sslmode=disable" \
version
# Принудительно установить версию (осторожно!)
migrate -path migrations \
-database "postgres://user:password@localhost:5432/ml_states?sslmode=disable" \
force VERSION
Использование схем
Если используется отдельная схема:
migrate -path migrations \
-database "postgres://user:password@localhost:5432/ml_states?sslmode=disable&search_path=ml_states" \
up
Структура миграций
000001_create_worker_progress
Создает таблицу worker_progress для отслеживания статуса обработки заданий.
Основные поля:
message_id(UUID, PRIMARY KEY) — уникальный идентификатор сообщенияstatus(VARCHAR) — статус: pending, processing, completed, failedworker_id(VARCHAR) — идентификатор воркераprogress_percent(DECIMAL) — процент выполненияcurrent_generation(INT) — текущее поколение GAintermediate_results(JSONB) — промежуточные результаты
Индексы:
idx_worker_progress_status— по статусу и времени обновленияidx_worker_progress_worker— по воркеру и статусуidx_worker_progress_updated— по времени обновления
000002_create_meta_learning_state
Создает таблицу meta_learning_state для хранения состояний Meta Learning, Transfer Learning и GA checkpoints.
Основные поля:
id(UUID, PRIMARY KEY) — уникальный идентификаторtest_id(VARCHAR) — ID конкретного тестаmessage_id(UUID) — связь с worker_progressstate_type(VARCHAR) — тип: meta_learning, transfer_learning, genetic_algorithmknowledge_key(VARCHAR) — составной ключ для глобальных знанийis_global(BOOLEAN) — флаг глобального состоянияstate_data(JSONB) — полное состояниеgeneration(INT) — текущее поколение GAcheckpoint_type(VARCHAR) — тип checkpointexpires_at(TIMESTAMP) — время истеченияversion(INT) — версия для оптимистичных блокировок
Индексы:
idx_meta_learning_knowledge_key— для поиска глобальных знанийidx_meta_learning_test_id— для поиска checkpoint’овidx_meta_learning_message_id— для поиска по message_ididx_meta_learning_exchange_pair_model— по комбинации полейidx_meta_learning_expires— для очистки истекших состоянийidx_meta_learning_global_unique— уникальный индекс для глобальных знаний
Создание новых миграций
Через golang-migrate CLI
# Создать новую миграцию
migrate create -ext sql -dir migrations -seq add_new_feature
# Это создаст:
# migrations/000003_add_new_feature.up.sql
# migrations/000003_add_new_feature.down.sql
Вручную
- Создайте файлы
00000N_<name>.up.sqlи00000N_<name>.down.sql - Реализуйте логику применения и отката
- Протестируйте миграции на тестовой БД
Пример новой миграции
000003_add_index.up.sql:
CREATE INDEX IF NOT EXISTS idx_meta_learning_created
ON meta_learning_state(created_at);
000003_add_index.down.sql:
DROP INDEX IF EXISTS idx_meta_learning_created;
Проверка применения миграций
Через SQL
-- Проверка версии миграций
SELECT version, dirty
FROM schema_migrations;
-- Проверка существования таблиц
SELECT table_name
FROM information_schema.tables
WHERE table_schema = 'public'
AND table_name IN ('worker_progress', 'meta_learning_state');
-- Проверка структуры таблицы
\d worker_progress
\d meta_learning_state
Через приложение
При старте приложения логируется информация о применении миграций:
✅ Миграции состояний применены
Откат миграций
Через golang-migrate
# Откатить последнюю миграцию
migrate -path migrations \
-database "postgres://user:password@localhost:5432/ml_states?sslmode=disable" \
down 1
# Откатить все миграции
migrate -path migrations \
-database "postgres://user:password@localhost:5432/ml_states?sslmode=disable" \
down -all
Внимание: Откат удалит данные из таблиц!
Troubleshooting
Миграции не применяются
- Проверьте путь к миграциям в конфигурации
- Проверьте права доступа к БД
- Проверьте логи приложения при старте
- Проверьте версию миграций:
migrate version
Ошибка “dirty database version”
Если миграция прервалась, база может остаться в “dirty” состоянии:
# Принудительно установить версию
migrate -path migrations \
-database "postgres://user:password@localhost:5432/ml_states?sslmode=disable" \
force VERSION
Конфликты при конкурентном доступе
Миграции применяются атомарно. Если несколько экземпляров приложения запускаются одновременно, только один применит миграции.
Рекомендация: Применяйте миграции вручную перед запуском приложения в production.
Рекомендации
- Development: Используйте
auto_migrate: trueдля удобства - Production: Применяйте миграции вручную перед деплоем
- CI/CD: Добавьте проверку миграций в pipeline
- Backup: Делайте backup БД перед применением миграций
- Testing: Тестируйте миграции на тестовой БД перед production
Интеграция с CI/CD
Пример для GitHub Actions
- name: Run migrations
run: |
migrate -path migrations \
-database "${{ secrets.DATABASE_URL }}?sslmode=disable" \
up
Пример для GitLab CI
migrate:
script:
- migrate -path migrations -database "$DATABASE_URL?sslmode=disable" up