До основного вмісту

Міграція PostgreSQL між серверами

Міграція · 07.02.2025 · 4 хв читання
Ілюстрація до статті «Міграція PostgreSQL між серверами»

Порядок перенесення PostgreSQL без падіння застосунку

PostgreSQL суворіше за MySQL ставиться до версій і кодувань, тому невдале перенесення найчастіше проявляється не порожньою базою, а помилками відновлення посеред процесу. Порядок нижче зводить цей ризик до мінімуму.

  1. Перевірте версію PostgreSQL на новому сервері — вона має бути рівною або новішою за версію на старому.
  2. Зробіть дамп на старому сервері, не зупиняючи застосунок.
  3. Відновіть дамп на новому сервері у порожню базу і звірте кількість рядків у ключових таблицях.
  4. Підключіть тестовий екземпляр застосунку до нової бази через змінні оточення, не чіпаючи продакшен.
  5. Перемкніть продакшен на нову базу лише після успішної перевірки, прийнявши коротке вікно простою на фінальну синхронізацію.

pg_dump: експорт бази даних

# Дамп однієї бази у custom формат (стиснений, паралельний restore)
pg_dump -U postgres -Fc -d mydb > mydb.dump

# Дамп у SQL-форматі (читабельний)
pg_dump -U postgres -d mydb > mydb.sql

# Лише схема (без даних)
pg_dump -U postgres --schema-only -d mydb > schema.sql

Логічна реплікація для мінімального простою

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

-- На старому сервері: публікація змін
CREATE PUBLICATION mydb_pub FOR ALL TABLES;

-- На новому сервері: підписка на публікацію
CREATE SUBSCRIPTION mydb_sub
  CONNECTION 'host=OLD_SERVER dbname=mydb user=repl_user password=secret'
  PUBLICATION mydb_pub;

pg_restore: імпорт на новому сервері

# Створюємо базу на новому сервері
createdb -U postgres mydb

# Відновлення з custom формату
pg_restore -U postgres -d mydb -j 4 mydb.dump
# -j 4 — використовувати 4 процеси паралельно
💡 Custom формат (Fc) відновлюється у 3–10 разів швидше ніж SQL, і підтримує паралельний restore з -j.

Швидке передавання через pipe

# Без збереження дампу на диску
pg_dump -U postgres -Fc mydb | ssh root@NEW_SERVER "pg_restore -U postgres -d mydb"

Порівняння форматів дампу

ФорматПрапорецьПаралельний restoreКоли використовувати
Custom-Fcтак (-j)стандартний вибір для перенесення між серверами
Plain SQLбез прапорцяніпотрібно вручну редагувати дамп перед відновленням
Directory-Fdтак (-j)дуже великі бази, потрібен паралельний сам дамп

Перевірка на новому сервері до перемикання

Підключіть тестовий екземпляр застосунку до нового сервера напряму за IP, не змінюючи DNS і не чіпаючи продакшен:

DATABASE_URL=postgresql://user:pass@NEW_SERVER_IP:5432/mydb ./run-app --dry-run

Пройдіть ключовими сценаріями застосунку — створення запису, пошук, звіт з агрегацією — і порівняйте результат із продакшеном на старій базі.

Перевірка після міграції

-- Порівнюємо кількість рядків
SELECT schemaname, tablename, n_live_tup
FROM pg_stat_user_tables
ORDER BY n_live_tup DESC;

Додатково перевірте, що всі послідовності (SEQUENCE) продовжуються з правильного значення — інакше нові записи почнуть конфліктувати за первинним ключем:

SELECT setval('orders_id_seq', (SELECT MAX(id) FROM orders));

Типові помилки під час відновлення

ПовідомленняПричина і рішення
FATAL: password authentication failed for userНе збігається метод автентифікації у pg_hba.conf на новому сервері — додайте рядок з md5 або scram-sha-256 для потрібного хоста
pg_restore: error: could not execute query: ERROR: relation already existsВідновлення в непорожню базу — створіть нову порожню базу або додайте прапорець --clean
ERROR: invalid byte sequence for encoding "UTF8"Вихідна база в іншому кодуванні — створіть нову базу з явним ENCODING, що збігається зі старою
pg_dump: error: server version mismatchВерсія pg_dump старша за версію сервера — використовуйте бінарник pg_dump тієї самої мажорної версії, що й сервер

Відкат у разі проблем

  1. Не вимикайте старий сервер, поки новий не відпрацював під реальним навантаженням хоча б добу.
  2. Якщо після перемикання застосунок працює нестабільно, поверніть DATABASE_URL на старий сервер — дані там не зачеплені.
  3. Розберіться з причиною на новому сервері у спокійному режимі і повторіть перенесення.

Коли це не підходить

Переконайтеся, що версія PostgreSQL на новому сервері >= версії на старому. Відкат на старішу версію не підтримується. Для баз більших за 100 ГБ або з вимогою нульового простою разовий pg_dump/pg_restore надто довгий — використовуйте логічну реплікацію з розділу вище або фізичну реплікацію через pg_basebackup.

Загальний план перевірки після будь-якої міграції описано у статті перевірка після міграції, а порядок безпечного відкату — у статті план відкату міграції.

Чи була стаття корисною?
← Назад до бази знань Поставити питання підтримці