Реализация миграции данных между версиями базы данных (zero-downtime)

Наша компания занимается разработкой, поддержкой и обслуживанием сайтов любой сложности. От простых одностраничных сайтов до масштабных кластерных систем построенных на микро сервисах. Опыт разработчиков подтвержден сертификатами от вендоров.
Разработка и обслуживание любых видов сайтов:
Информационные сайты или веб-приложения
Сайты визитки, landing page, корпоративные сайты, онлайн каталоги, квиз, промо-сайты, блоги, новостные ресурсы, информационные порталы, форумы, агрегаторы
Сайты или веб-приложения электронной коммерции
Интернет-магазины, B2B-порталы, маркетплейсы, онлайн-обменники, кэшбэк-сайты, биржи, дропшиппинг-платформы, парсеры товаров
Веб-приложения для управления бизнес-процессами
CRM-системы, ERP-системы, корпоративные порталы, системы управления производством, парсеры информации
Сайты или веб-приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, конструкторы сайтов, порталы предоставления электронных услуг, видеохостинги, тематические порталы

Это лишь некоторые из технических типов сайтов, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента

Предлагаемые услуги
Показано 1 из 1 услугВсе 2065 услуг
Реализация миграции данных между версиями базы данных (zero-downtime)
Сложная
~3-5 рабочих дней
Часто задаваемые вопросы
Наши компетенции:
Этапы разработки
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1262
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1171
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    874
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1094
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    831
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Разработка веб-сайта для компании ФИКСПЕР
    851

Реализация миграции данных между версиями базы данных (zero-downtime)

Zero-downtime миграция БД — переход на новую версию PostgreSQL, MySQL или другой СУБД без остановки приложения. Требует специального подхода к схеме, переносу данных и переключению трафика.

Принципы zero-downtime миграций

Любое изменение схемы БД проходит через backward-compatible этапы:

  1. Добавить новое (колонку, таблицу) — приложение игнорирует новое
  2. Задеплоить код, который пишет в оба места
  3. Мигрировать существующие данные батчами
  4. Задеплоить код, который читает только из нового
  5. Удалить старое

Никаких DROP COLUMN и RENAME COLUMN в production за один шаг.

Обновление PostgreSQL в мажорной версии (pg_upgrade)

Способ 1: pg_upgrade с репликой

# 1. Поднять новую версию PostgreSQL рядом
apt install postgresql-15

# 2. Остановить запись (короткий даунтайм для подготовки)
pg_ctl -D /var/lib/postgresql/14/main stop

# 3. pg_upgrade в режиме --link (без копирования файлов)
/usr/lib/postgresql/15/bin/pg_upgrade \
  --old-datadir=/var/lib/postgresql/14/main \
  --new-datadir=/var/lib/postgresql/15/main \
  --old-bindir=/usr/lib/postgresql/14/bin \
  --new-bindir=/usr/lib/postgresql/15/bin \
  --link \
  --check  # сначала проверка без выполнения

# 4. Выполнить upgrade
/usr/lib/postgresql/15/bin/pg_upgrade \
  --old-datadir=/var/lib/postgresql/14/main \
  --new-datadir=/var/lib/postgresql/15/main \
  --old-bindir=/usr/lib/postgresql/14/bin \
  --new-bindir=/usr/lib/postgresql/15/bin \
  --link

Режим --link использует hardlinks вместо копирования — для базы в 100GB занимает секунды вместо часов. Недостаток: старую версию после этого не запустить.

Способ 2: Logical Replication (настоящий zero-downtime)

-- На старом сервере (PG 13)
CREATE PUBLICATION migration_pub FOR ALL TABLES;

-- На новом сервере (PG 15) — создать ту же схему
pg_dump -s -U postgres myapp | psql -U postgres -h new-server myapp

-- Подписка на репликацию
CREATE SUBSCRIPTION migration_sub
  CONNECTION 'host=old-server dbname=myapp user=replication password=pass'
  PUBLICATION migration_pub;

-- Следить за прогрессом первоначальной синхронизации
SELECT subname, received_lsn, latest_end_lsn
FROM pg_stat_subscription;

После синхронизации:

-- Проверить лаг (должен быть близок к нулю)
SELECT now() - last_msg_receipt_time AS subscription_lag
FROM pg_stat_subscription;

-- Переключение: остановить запись в старую БД, дождаться лага = 0
-- Обновить connection string в приложении
-- Удалить подписку
DROP SUBSCRIPTION migration_sub;

Схемные миграции без даунтайма

Добавление NOT NULL колонки

Нельзя в один шаг — ALTER TABLE заблокирует таблицу на всё время DEFAULT-вычисления.

Правильно:

-- Шаг 1: добавить колонку с DEFAULT (PostgreSQL 11+ — instant)
ALTER TABLE users ADD COLUMN phone VARCHAR(20) DEFAULT NULL;

-- Шаг 2: заполнить данными батчами
DO $$
DECLARE
  batch_size INT := 1000;
  offset_val INT := 0;
BEGIN
  LOOP
    UPDATE users SET phone = '' WHERE id IN (
      SELECT id FROM users WHERE phone IS NULL ORDER BY id LIMIT batch_size
    );
    EXIT WHEN NOT FOUND;
    PERFORM pg_sleep(0.01);  -- пауза между батчами
  END LOOP;
END $$;

-- Шаг 3: добавить NOT NULL constraint (быстро, если нет NULL)
ALTER TABLE users ALTER COLUMN phone SET NOT NULL;

Переименование колонки

-- Шаг 1: добавить новую колонку
ALTER TABLE orders ADD COLUMN customer_id BIGINT;

-- Шаг 2: заполнить данными (+ триггер для новых записей)
CREATE OR REPLACE FUNCTION sync_customer_id() RETURNS TRIGGER AS $$
BEGIN
  NEW.customer_id := NEW.user_id;
  RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER sync_customer_id_trigger
BEFORE INSERT OR UPDATE ON orders
FOR EACH ROW EXECUTE FUNCTION sync_customer_id();

-- Батчевое заполнение существующих записей
UPDATE orders SET customer_id = user_id WHERE customer_id IS NULL;

-- Шаг 3: задеплоить код, читающий customer_id
-- Шаг 4: удалить старую колонку и триггер
ALTER TABLE orders DROP COLUMN user_id;
DROP TRIGGER sync_customer_id_trigger ON orders;

Инструменты

gh-ost (GitHub) — online schema migration для MySQL без блокировок:

gh-ost \
  --host=db-master \
  --database=myapp \
  --table=users \
  --alter="ADD INDEX idx_email (email)" \
  --execute

pg-osc — аналог для PostgreSQL.

Flyway / Liquibase — управление версиями миграций с поддержкой undo.

Тестирование плана миграции

# Восстановить production dump в staging
pg_restore -U postgres -d myapp_staging production.dump

# Проверить план миграции
psql -U postgres myapp_staging < migration_plan.sql

# Замерить время выполнения
\timing on
\i migration_plan.sql

Срок выполнения

Zero-downtime обновление PostgreSQL с logical replication — 2–3 дня. Комплексная схемная миграция с несколькими шагами — 1–2 недели (включая тестирование и staging).