[Документация Yandex Cloud](../../index.md) > [Yandex Data Transfer](../index.md) > [Практические руководства](index.md) > Миграция > Миграция кластера Managed Service for PostgreSQL на другую версию

# Миграция кластера Yandex Managed Service for PostgreSQL на другую версию c помощью Data Transfer

# Миграция кластера Managed Service for PostgreSQL на другую версию c помощью Yandex Data Transfer

{% note warning %}

Этот документ не применим для пользователей Yandex Cloud в [регионе Казахстан](../../overview/concepts/region.md). Смотрите полный перечень [поддерживаемых эндпоинтов](../transfer-matrix.md) в Data Transfer.

{% endnote %}

Вы можете перенести продуктивную нагруженную базу данных, развернутую в кластере Managed Service for PostgreSQL, в кластер со старшей версией. В этом руководстве рассматривается пример переноса с версии 14 сразу на версию 17, без последовательного переноса между несколькими версиями (14 → 15 → 16 → 17).

{% note warning %}

Начиная с 12 августа 2026 года, существующие кластеры PostgreSQL версии 14 будут автоматически обновляться до версии 15. Рекомендуем заранее обновиться самостоятельно.

{% endnote %}

Чтобы перенести данные:

1. [Подготовьте кластер-источник](#prepare-source).
1. [Подготовьте кластер-приемник](#prepare-target).
1. [Подготовьте и активируйте трансферы](#prepare-transfer).
1. [Переключитесь на работу с новым кластером](#move-data).
1. [Проверьте перенос данных](#verify).

Если созданные ресурсы вам больше не нужны, [удалите их](#clear-out).


## Необходимые платные ресурсы {#paid-resources}

* Кластер Managed Service for PostgreSQL: выделенные хостам вычислительные ресурсы, объем хранилища и резервных копий ([тарифы Managed Service for PostgreSQL](../../managed-postgresql/pricing.md)).
* Публичные IP-адреса, если для хостов кластера включен публичный доступ ([тарифы Virtual Private Cloud](../../vpc/pricing.md)).
* Каждый трансфер: использование вычислительных ресурсов и количество переданных строк данных ([тарифы Data Transfer](../pricing.md)).


## Подготовьте кластер-источник {#prepare-source}

1. Подготовьте базу-источник к миграции в соответствии с [рекомендациями](../operations/prepare.md#source-pg).

1. Оцените нагрузку на базу данных. Если она превышает 10 000 операций на запись в секунду, запланируйте несколько трансферов:

    1. Определите список особо нагруженных таблиц.
    1. Распределите таблицы между несколькими трансферами.

## Подготовьте кластер-приемник {#prepare-target}

1. Создайте кластер-приемник Managed Service for PostgreSQL:

    {% list tabs group=instructions %}

    - Вручную {#manual}

        [Создайте кластер-приемник Managed Service for PostgreSQL](../../managed-postgresql/operations/cluster-create.md) с конфигурацией, идентичной кластеру-источнику, и со следующими настройками:

        * Версия кластера — `17`.
        * Имя базы данных — `db1`.
        * Имя пользователя — `user1`.

        Если вы планируете подключаться к кластеру из интернета, включите публичный доступ к хостам кластера.

    - С помощью Terraform {#tf}

        1. Если у вас еще нет Terraform, [установите его](../../tutorials/infrastructure-management/terraform-quickstart.md#install-terraform).
        1. [Получите данные для аутентификации](../../tutorials/infrastructure-management/terraform-quickstart.md#get-credentials). Вы можете добавить их в переменные окружения или указать далее в файле с настройками провайдера.
        1. [Настройте и инициализируйте провайдер](../../tutorials/infrastructure-management/terraform-quickstart.md#configure-provider). Чтобы не создавать конфигурационный файл с настройками провайдера вручную, [скачайте его](https://github.com/yandex-cloud-examples/yc-terraform-provider-settings/blob/main/provider.tf).
        1. Поместите конфигурационный файл в отдельную рабочую директорию и [укажите значения параметров](../../tutorials/infrastructure-management/terraform-quickstart.md#configure-provider). Если данные для аутентификации не были добавлены в переменные окружения, укажите их в конфигурационном файле.

        1. В той же рабочей директории разместите файл с расширением `.tf` и содержимым:

            ```hcl
            resource "yandex_mdb_postgresql_cluster" "old" { }
            ```

        1. Запишите идентификатор кластера PostgreSQL версии 13 в переменную окружения:

            ```bash
            export POSTGRESQL_CLUSTER_ID=<идентификатор_кластера>
            ```

            Идентификатор можно запросить вместе со [списком кластеров в каталоге](../../managed-postgresql/operations/cluster-list.md#list-clusters).

        1. Импортируйте настройки кластера PostgreSQL версии 13 в конфигурацию Terraform:

            ```bash
            terraform import yandex_mdb_postgresql_cluster.old ${POSTGRESQL_CLUSTER_ID}
            ```

        1. Получите импортированную конфигурацию:

            ```bash
            terraform show
            ```

        1. Скопируйте ее из терминала и вставьте в файл с расширением `.tf`.
        1. Расположите файл в новой директории `imported-cluster`.
        1. Измените скопированную конфигурацию так, чтобы из нее можно было создать новый кластер:

            * Укажите новое имя кластера в строке `resource` и параметре `name`.
            * В блоке `config` укажите в параметре `version` версию `17`.
            * Удалите параметры `created_at`, `health`, `id` и `status`.
            * В блоках `host` удалите параметры `fqdn`, `role` и `priority`.
            * Если в блоке `disk_size_autoscaling` указано значение параметра `disk_size_limit = 0`, удалите этот блок.
            * Если в блоке `maintenance_window` указано значение параметра `type = "ANYTIME"`, удалите параметр `hour`.
            * (Опционально) Внесите дополнительные изменения, если вам нужна не идентичная, а кастомизированная копия кластера.

        1. Добавьте в файл ресурс для создания пользователя `user1`:

            ```hcl
            resource "yandex_mdb_postgresql_user" "user1" {
              cluster_id = yandex_mdb_postgresql_cluster.<имя_кластера>.id
              name       = "user1"
              password   = "<пароль_пользователя>"
            }
            ```

            Где `<имя_кластера>` — новое имя кластера, указанное в ресурсе `yandex_mdb_postgresql_cluster`.

        1. Добавьте в файл ресурс для создания базы данных:

            ```hcl
            resource "yandex_mdb_postgresql_database" "db1" {
              cluster_id = yandex_mdb_postgresql_cluster.<имя_кластера>.id
              name       = "db1"
              owner      = yandex_mdb_postgresql_user.user1.name
              depends_on = [yandex_mdb_postgresql_user.user1]
            }
            ```

            Где `<имя_кластера>` — новое имя кластера, указанное в ресурсе `yandex_mdb_postgresql_cluster`.

        1. В директории `imported-cluster` [получите данные для аутентификации](../../tutorials/infrastructure-management/terraform-quickstart.md#get-credentials).

        1. В этой же директории [настройте и инициализируйте провайдер](../../tutorials/infrastructure-management/terraform-quickstart.md#configure-provider). Чтобы не создавать конфигурационный файл с настройками провайдера вручную, [скачайте его](https://github.com/yandex-cloud-examples/yc-terraform-provider-settings/blob/main/provider.tf).

        1. Поместите конфигурационный файл в директорию `imported-cluster` и [укажите значения параметров](../../tutorials/infrastructure-management/terraform-quickstart.md#configure-provider). Если данные для аутентификации не были добавлены в переменные окружения, укажите их в конфигурационном файле.

        1. Проверьте корректность файлов конфигурации Terraform:

            ```bash
            terraform validate
            ```

            Если в файлах конфигурации есть ошибки, Terraform на них укажет.

        1. Создайте необходимую инфраструктуру:

            1. Выполните команду для просмотра планируемых изменений:
            
               ```bash
               terraform plan
               ```
            
               Если конфигурации ресурсов описаны верно, в терминале отобразится список изменяемых ресурсов и их параметров. Это проверочный этап: ресурсы не будут изменены.
            
            1. Если вас устраивают планируемые изменения, внесите их:
               1. Выполните команду:
            
                  ```bash
                  terraform apply
                  ```
            
               1. Подтвердите изменение ресурсов.
               1. Дождитесь завершения операции.

            В указанном каталоге будут созданы все требуемые ресурсы. Проверить появление ресурсов и их настройки можно в [консоли управления](https://kz.console.yandex.cloud).

        {% note warning "Ограничения по времени" %}
        
        Провайдер Terraform ограничивает время на выполнение операций с кластером Managed Service for PostgreSQL:
        
        * создание, в том числе путем восстановления из резервной копии, — 30 минут;
        * изменение — 60 минут;
        * удаление — 15 минут.
        
        Операции, длящиеся дольше указанного времени, прерываются.
        
        {% cut "Как изменить эти ограничения?" %}
        
        Добавьте к описанию кластера блок `timeouts`, например:
        
        ```hcl
        resource "yandex_mdb_postgresql_cluster" "<имя_кластера>" {
          ...
          timeouts {
            create = "1h30m" # Полтора часа
            update = "2h"    # 2 часа
            delete = "30m"   # 30 минут
          }
        }
        ```
        
        {% endcut %}
        
        {% endnote %}

    {% endlist %}


1. Если вы используете группы безопасности в кластере, убедитесь, что они [настроены правильно](../../managed-postgresql/operations/connect/index.md#configuring-security-groups) и допускают подключение к нему.


1. Подготовьте базу-приемник к миграции в соответствии с [рекомендациями](../operations/prepare.md#target-pg).

## Подготовьте и активируйте трансферы {#prepare-transfer}

{% list tabs group=instructions %}

- Вручную {#manual}

    1. [Создайте эндпоинт-источник](../operations/endpoint/index.md#create) для каждого запланированного трансфера и укажите параметры эндпоинта:

        * **Тип базы данных** — `PostgreSQL`.
        * **Тип подключения** — `Ручная настройка`.
        * **Тип инсталляции** — `Кластер Managed Service for PostgreSQL`.
        * **Кластер управляемой БД** — `<имя_кластера-источника>` из выпадающего списка.
        * **База данных** — `<имя_базы_данных_кластера-источника>`.
        * **Пользователь** — `<имя_пользователя>`.
        * **Пароль** — `<пароль>`.
        * **Список включенных таблиц** — для каждого эндпоинта укажите список включенных таблиц в соответствии с планом распределения по трансферам.

        Убедитесь, что в блоке **Перенос схемы** для внешних ключей и индексов установлено значение `После переноса данных`. В этом случае перенос внешних ключей и индексов будет выполняться на этапе деактивации трансферов.

    1. [Создайте эндпоинт-приемник](../operations/endpoint/index.md#create) для каждого запланированного трансфера и укажите параметры эндпоинта:

        * **Тип базы данных** — `PostgreSQL`.
        * **Тип подключения** — `Ручная настройка`.
        * **Тип инсталляции** — `Кластер Managed Service for PostgreSQL`.
        * **Кластер управляемой БД** — `db1` из выпадающего списка.
        * **Пользователь** — `user1`.
        * **Пароль** — `<пароль>`.

    1. [Создайте трансферы](../operations/transfer.md#create) типа **_Копирование и репликация_**, использующие созданные эндпоинты.

        Чтобы ускорить копирование больших таблиц (более 100 ГБ), настройте [параллельное копирование](../concepts/sharded.md) для трансфера, указав нужное количество воркеров и потоков.

        Таблица разделится на указанное количество частей, которые будут копироваться параллельно.

    1. [Активируйте трансферы](../operations/transfer.md#activate).

- С помощью Terraform {#tf}

    1. Откройте в папке `imported-cluster` конфигурационный файл Terraform с планом инфраструктуры.
    1. Добавьте в файл ресурс для создания эндпоинта-источника.

        ```hcl
        resource "yandex_datatransfer_endpoint" "<имя_эндпоинта>" {
          name = "<имя_эндпоинта>"
            settings {
              postgres_source {
                connection {
                  mdb_cluster_id = "<идентификатор_кластера-источника>"
                }
                database = "<имя_базы_данных>"
                user     = "<имя_пользователя>"
                password {
                  raw = "<пароль>"
                }
                include_tables = ["<схема>.<таблица_1>", ... , "<схема>.<таблица_N>"]
                object_transfer_settings {
                  fk_constraint = "AFTER_DATA"
                  index         = "AFTER_DATA"
                }
              }
            }
        }
        ```

        Если вы запланировали несколько трансферов, добавьте отдельный эндпоинт для каждого из них. Для каждого эндпоинта-источника укажите в параметре `include_tables` список включенных таблиц в соответствии с планом распределения по трансферам.

        В блоке `object_transfer_settings` определены параметры переноса схемы. Значение `AFTER_DATA` означает, что внешние ключи и индексы будут переноситься после переноса данных (на этапе деактивации трансферов).

    1. Добавьте в файл ресурс для создания эндпоинта-приемника.

        ```hcl
        resource "yandex_datatransfer_endpoint" "<имя_эндпоинта>" {
          name = "<имя_эндпоинта>"
            settings {
              postgres_target {
                connection {
                  mdb_cluster_id = yandex_mdb_postgresql_cluster.<имя_кластера>.id
                }
                database = "db1"
                user     = "user1"
                password {
                  raw = "<пароль>"
                }
              }
            }
        }
        ```

        Где `<имя_кластера>` — имя кластера, указанное в ресурсе `yandex_mdb_postgresql_cluster`.

        Если вы запланировали несколько трансферов, добавьте отдельный эндпоинт для каждого из них.

    1. Добавьте в файл ресурс для создания трансфера, использующего созданные эндпоинты.

        ```
        resource "yandex_datatransfer_transfer" "<имя_трансфера>" {
          name      = "<имя_трансфера>"
          source_id = yandex_datatransfer_endpoint.<имя_эндпоинта-источника>.id
          target_id = yandex_datatransfer_endpoint.<имя_эндпоинта-приемника>.id
          type      = "SNAPSHOT_AND_INCREMENT"
          runtime {
            yc_runtime {
              upload_shard_params {
                job_count     = <количество_воркеров>
                process_count = <количество_потоков>
              }
            }
          }
        }
        ```

        Где:

        * `source_id` — ссылка на эндпоинт-источник.
        * `target_id` — ссылка на эндпоинт-приемник.
        * `type` — тип трансфера. Значение `SNAPSHOT_AND_INCREMENT` — **_Копирование и репликация_**.
        * `runtime.yc_runtime.upload_shard_params` — настройки [параллельного копирования](../concepts/sharded.md). Используются, чтобы ускорить копирование больших таблиц (более 100 ГБ).

            * `job_count` — количество воркеров.
            * `process_count` — количество потоков.

        Если вы распределили таблицы между несколькими парами эндпоинтов, создайте отдельный трансфер для каждой из них.

        Трансферы будут запущены автоматически после создания.

{% endlist %}

## Переключитесь на работу с новым кластером {#move-data}

1. Дождитесь перехода трансферов в статус **Реплицируется**.
1. Снимите пишущую нагрузку с кластера-источника.
1. На странице [мониторинга трансфера](../operations/monitoring.md) дождитесь снижения до нуля характеристики **Maximum data transfer delay** для каждого трансфера. Это значит, что в кластер-приемник перенесены все изменения, произошедшие в кластере-источнике после завершения копирования данных.
1. Переключите нагрузку на кластер-приемник.
1. [Деактивируйте](../operations/transfer.md#deactivate) трансферы и дождитесь их перехода в статус **Остановлен**.

    Во время деактивации выполняется создание внешних ключей и индексов. Это может занять продолжительное время. Чем больший объем занимает база данных, тем больше времени занимает деактивация.

## Проверьте перенос данных {#verify}

1. [Подключитесь к базе данных](../../managed-postgresql/operations/connect/index.md) `db1` в кластере-приемнике Managed Service for PostgreSQL.

1. Убедитесь, что в базе данных `db1` появились таблицы, выполнив запрос:

    ```sql
    SELECT schemaname AS schema, tablename AS table_name
    FROM pg_tables
    WHERE schemaname NOT IN ('pg_catalog', 'information_schema') 
      AND tablename NOT LIKE 'pg\_%'
    ORDER BY schemaname, tablename;
    ```

    Запрос выведет список всех несистемных таблиц.

## Удалите созданные ресурсы {#clear-out}

Некоторые ресурсы платные. Удалите ресурсы, которые вы больше не будете использовать, чтобы не платить за них:

{% list tabs group=instructions %}

- Вручную {#manual}

    1. [Удалите трансфер](../operations/transfer.md#delete).
    1. [Удалите эндпоинты](../operations/endpoint/index.md#delete).
    1. [Удалите кластер Managed Service for PostgreSQL](../../managed-postgresql/operations/cluster-delete.md) версии `17`.

- С помощью Terraform {#tf}

    1. В терминале перейдите в директорию с планом инфраструктуры.
    
        {% note warning %}
    
        Убедитесь, что в директории нет Terraform-манифестов с ресурсами, которые вы хотите сохранить. Terraform удаляет все ресурсы, которые были созданы с помощью манифестов в текущей директории.
    
        {% endnote %}
    
    1. Удалите ресурсы:
    
        1. Выполните команду:
    
            ```bash
            terraform destroy
            ```
    
        1. Подтвердите удаление ресурсов и дождитесь завершения операции.
    
        Все ресурсы, которые были описаны в Terraform-манифестах, будут удалены.

{% endlist %}