Миграция баз данных PostgreSQL в облачные базы данных

Вы можете перенести данные из своей базы данных PostgreSQL в облачные базы данных Selectel с помощью логической репликации или с помощью логического дампа.

Перед миграцией создайте принимающий кластер баз данных PostgreSQL с версией не ниже, чем у исходного кластера. Если вы выбрали способ миграции с помощью логического дампа, то версии кластеров должны совпадать.

Логическая репликация

В логической репликации используется модель публикаций и подписок с одним или несколькими подписчиками. Они подписываются на одну или несколько публикаций на публикующем узле. На внешнем исходном кластере PostgreSQL создается публикация, на которую подписывается принимающий кластер облачных баз данных.

  1. Подготовьте исходный кластер.
  2. Перенесите схему базы данных.
  3. Создайте публикацию на исходном кластере.
  4. Создайте подписку на принимающем кластере.

Подготовить исходный кластер

  1. Добавьте пользователю с доступом к реплицируемым данным привилегию replication:

    ALTER ROLE <user_name> WITH REPLICATION;

    Укажите <user_name> — имя пользователя.

  2. В файле postgresql.conf установите для уровня логирования (Write Ahead Log) значение logical:

    wal_level = logical
  3. В файле pg_hba.conf настройте аутентификацию:

    host         all            all             <host>      md5
    host         replication    all             <host>      md5

    Укажите <host> — IP-адрес или DNS-имя мастер-хоста принимающего кластера.

  4. Перезапустите PostgreSQL для применения изменений:

    systemctl restart postgresql

Перенести схему базы данных

На исходном и принимающем кластере должна быть одинаковая схема базы данных.

  1. Создайте дамп схемы на исходном кластере с помощью утилиты pg_dump:

    pg_dump \
    -h <host> \
    -p <port> \
    -d <database_name> \
    -U <user_name> \
    --schema-only \
    --no-privileges \
    --no-subscriptions \
    --no-publications \
    -Fd -f <dump_directory>

    Укажите:

    • <host> — IP-адрес или DNS-имя мастер-хоста исходного кластера;
    • <port> — порт;
    • <database_name> — имя базы данных;
    • <user_name> — имя пользователя базы данных;
    • <dump_directory> — путь до дампа.
  2. Восстановите схему из дампа на принимающем кластере с помощью утилиты pg_restore:

    pg_restore \
    -Fd -v \ 
    --single-transaction -s \
    --no-privileges \
    -O \
    -h <host> \
    -U <user_name> \
    -p 6432 \
    -d <database_name> \
    <dump_directory>

    Укажите:

    • <host> — IP-адрес или DNS-имя хоста принимающего кластера;
    • <user_name> — имя пользователя базы данных;
    • <database_name> — имя базы данных;
    • <dump_directory> — путь до дампа.

Создать публикацию на исходном кластере

Для создания публикации сразу для всех таблиц нужны права суперпользователя.

Создайте публикацию для таблиц, которые вы хотите перенести:

CREATE PUBLICATION <publication_name> FOR ALL TABLES;

Укажите <publication_name> — имя публикации.

Создать подписку на принимающем кластере

В принимающем кластере облачных баз данных подписки может использовать только пользователь с ролью dbaas_admin.

  1. Создайте подписку от имени пользователя с ролью dbaas_admin:

    CREATE SUBSCRIPTION <subscription_name> CONNECTION \
    'host=<host> \
    port=<port> \
    dbname=<database_name> \
    user=<user_name> \
    password=<password> \
    sslmode=verify-ca' \
    PUBLICATION <publication_name>;

    Укажите:

    • <subscription_name> — имя подписки;
    • <host> — IP-адрес или DNS-имя мастер-хоста исходного кластера;
    • <port> — порт;
    • <user_name> — имя пользователя базы данных;
    • <password> — пароль пользователя;
    • <database_name> — имя базы данных;
    • <publication_name> — имя публикации.
  2. Вы можете следить за статусом репликации с помощью каталога pg_subscription_rel:

    SELECT * FROM pg_subscription_rel;

    Общее состояние репликации вы можете увидеть в представлениях pg_stat_subscription и pg_stat_replication для подписок и публикаций соответственно.

  3. Последовательности (sequences) не реплицируются, поэтому перед переносом нагрузки на принимающий кластер восстановите на нем дамп с sequences, если они используются. Также перед переносом нагрузки удалите подписку в принимающем кластере:

    DROP SUBSCRIPTION <subscription_name>;

    Укажите <subscription_name> — имя подписки.

Логический дамп

Создайте дамп (файл с командами для восстановления) базы данных в исходном кластере и восстановите дамп в принимающем кластере.

Вы можете создать SQL-дамп всех баз данных (сохранятся имя, таблицы, индексы и внешние ключи) или дамп в кастомном формате (например, можно восстановить только схему или данные специфичной таблицы).

Если вы используете порты PgBouncer 6432 или 5433, измените режим пулинга PgBouncer на session. Если для PgBouncer будет включен другой режим пулинга, могут измениться search_path для части соединений, и таблицы будут недоступны по неполному имени.

SQL-дамп

  1. Создайте дамп базы данных в исходном кластере с помощью утилиты pg_dump:

    pg_dump \
    -h <host> \
    -U <user_name> \
    -d <database_name> \
    -f dump.sql

    Укажите:

    • <host> — IP-адрес или DNS-имя мастер-хоста исходного кластера;
    • <user_name> — имя пользователя;
    • <database_name> — имя базы данных.
  2. Восстановите дамп в принимающем кластере с помощью утилиты psql:

    psql \
    -f dump.sql \
    -h <host> \
    -p 6432 \
    -U <user_name> \
    -d <database_name>

    Укажите:

    • <host> — IP-адрес или DNS-имя мастер-хоста принимающего кластера;
    • <user_name> — имя пользователя базы данных;
    • <database_name> — имя базы данных.

Кастомный дамп

Копия базы данных в кастомном формате по умолчанию сжимается.

  1. Создайте дамп базы данных в исходном кластере с помощью утилиты pg_dump:

    pg_dump \
    -Fc -v \
    -h <host> \
    -U <user_name> \
    <database_name> > archive.dump

    Укажите:

    • <host> — IP-адрес или DNS-имя мастер-хоста исходного кластера;
    • <user_name> — имя пользователя базы данных;
    • <database_name> — имя базы данных.
  2. Восстановите дамп в принимающем кластере с помощью утилиты pg_restore:

    pg_restore \
    -v
    -h <host> \
    -U <user_name>
    -d <database_name> archive.dump

    Укажите:

    • <host> — IP-адрес или DNS-имя мастер-хоста принимающего кластера;
    • <user_name> — имя пользователя базы данных;
    • <database_name> — имя базы данных.