---
title: 'Перенести данные из PostgreSQL в облачную базу данных PostgreSQL с помощью Trino'
sidebar_label: 'Перенести данные из PostgreSQL в облачную базу данных PostgreSQL с помощью Trino'
sidebar_position: 1
description: 'Как перенести данные из PostgreSQL в облачную базу данных PostgreSQL с помощью Trino'
---

import {CustomTable} from '@selectel/docux/components'

# Перенести данные из PostgreSQL в облачную базу данных PostgreSQL с помощью Trino

Вы можете перенести таблицы из своей базы данных PostgreSQL — на собственном сервере или в другом облаке — в [облачную базу данных PostgreSQL](/managed-databases/postgresql) с помощью [облака для Trino](/cloud-for-trino/about/about-cloud-for-trino.mdx). Trino читает данные из исходной базы и записывает их в целевую одним SQL-запросом, без промежуточных дампов и файлов.

Способ подходит, если нужно перенести отдельные схемы или таблицы, отфильтровать или преобразовать данные при переносе. Чтобы перенести базу данных целиком вместе с индексами, ключами, функциями и триггерами, используйте [логическую репликацию или логический дамп](/managed-databases/postgresql/database-migration.mdx).

Облако для Trino находится на стадии публичного тестирования (public preview) и доступно только в пуле ru-7 — подробнее в инструкции [Доступность облака для Trino в локациях](/cloud-for-trino/about/cloud-for-trino-availability-by-location.mdx). Все ресурсы из этой инструкции создавайте в пуле ru-7.

## Как устроена миграция

Кластер Trino и кластер облачных баз данных PostgreSQL находятся в одной приватной подсети:

* к целевой базе Trino подключается по приватной подсети;
* к исходной базе Trino подключается через интернет — для этого приватная подсеть подключена к облачному роутеру с доступом в интернет. Роутер выпускает трафик подсети в интернет через свой внешний IP-адрес;
* SQL-запросы вы отправляете в Trino со своего компьютера через внешний доступ к кластеру Trino.

Схема миграции: исходная база → облачный роутер → кластер Trino → кластер PostgreSQL.

Исходная и целевая базы подключаются к Trino как два [каталога](/cloud-for-trino/manage/catalogs.mdx) с коннектором PostgreSQL. В одном SQL-запросе можно читать данные из одного каталога и записывать их в другой.

## Что нужно для миграции

* исходная база данных PostgreSQL, доступная из интернета по публичному IP-адресу или DNS-адресу;
* права на создание пользователей в исходной базе, доступ к файлам `pg_hba.conf` и `postgresql.conf` и к файрволу сервера;
* компьютер с клиентом для подключения к Trino — [Trino CLI](https://trino.io/docs/current/client/cli.html) или [DBeaver](https://dbeaver.io/download/);
* optional: Python 3.9 или выше — если вы будете переносить данные с помощью скрипта.

В инструкции используются имена из примера — замените их на свои:

<CustomTable>
  <table>
    <tbody>
      <tr>
        <td>Приватная сеть</td>
        <td>  trino-migration-net </td>
      </tr>

      <tr>
        <td>Облачный роутер</td>
        <td>  trino-migration-router </td>
      </tr>

      <tr>
        <td>Кластер облачных баз данных PostgreSQL</td>
        <td> pg-target </td>
      </tr>

      <tr>
        <td>Пользователь целевой базы данных</td>
        <td> trino_writer </td>
      </tr>

      <tr>
        <td>Кластер Trino</td>
        <td> trino-migration </td>
      </tr>

      <tr>
        <td>Каталог Trino для исходной базы данных</td>
        <td> pg_source </td>
      </tr>

      <tr>
        <td>Каталог Trino для целевой базы данных</td>
        <td> pg_target </td>
      </tr>

      <tr>
        <td>Пользователь исходной базы данных</td>
        <td> trino_reader </td>
      </tr>

      <tr>
        <td>Схема и таблица для переноса</td>
        <td> public.users </td>
      </tr>
    </tbody>
  </table>
</CustomTable>

## Шаги миграции

1. Настройте сеть.

2. Подготовьте исходную базу данных.

3. Создайте кластер облачной базы данных PostgreSQL.

4. Создайте кластер Trino с каталогами.

5. Подключитесь к кластеру Trino и проверьте каталоги.

6. Перенесите данные.

7. Проверьте результат.

### 1. Настроить сеть

Кластер Trino и кластер облачных баз данных создаются в одной приватной подсети. Чтобы Trino мог подключиться к исходной базе через интернет, подключите подсеть к облачному роутеру с доступом в интернет. Подробнее в подразделе [Настроить доступ в интернет через облачный роутер](/cloud-servers/cloud-networks/configure-access-to-internet.mdx#internet-access-via-cloud-router).

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

   1.1. В [панели управления](https://my.selectel.ru/vpc/default/networks/) в верхнем меню нажмите **Продукты** и выберите **Облачные серверы**.

   1.2. Перейдите в раздел **Сеть** → вкладка **Приватные сети**.

   1.3. Нажмите **Создать сеть**.

   1.4. Выберите [локацию](/infrastructure/locations.mdx) — пул ru-7.

   1.5. Введите имя сети — trino-migration-net.

   1.6. Введите CIDR подсети, например `192.168.0.0/24`.

   1.7. Нажмите **Создать**.

2. Создайте облачный роутер с подключением к интернету:

   2.1. В [панели управления](https://my.selectel.ru/vpc/default/routers/) в верхнем меню нажмите Продукты и выберите Облачные серверы.

   2.2 Перейдите в раздел **Сеть** → вкладка **Облачные роутеры**.

   2.3. Нажмите **Создать роутер**.

   2.4. Выберите локацию — пул ru-7.

   2.5. Выберите тип роутера.

   2.6. Введите имя роутера — trino-migration-router.

   2.7. Отметьте чекбокс **Подключить роутер к интернету** — для роутера будет выделен внешний IP-адрес.

   2.8. Нажмите **Создать**.

3. Подключите подсеть к облачному роутеру:

   3.1. Откройте страницу роутера trino-migration-router.

   3.2. Нажмите **Подключить подсеть**.

   3.3. Выберите подсеть сети trino-migration-net.

   3.4. Введите IP-адрес роутера — [шлюз подсети](/cloud-servers/cloud-networks/private-networks-and-subnets.mdx#default-gateway), например `192.168.0.1`. Если IP-адрес роутера совпадает со шлюзом подсети, устройства в подсети выходят в интернет без дополнительных маршрутов.

   3.5. Нажмите **Подключить**.

4. Скопируйте внешний IP-адрес роутера — он понадобится, чтобы разрешить подключение к исходной базе данных. Можно посмотреть на странице роутера.

### 2. Подготовить исходную базу данных

Trino подключается к исходной базе от имени отдельного пользователя с правами только на чтение — так миграция не изменит данные в исходной базе.

1. Подключитесь к исходной базе данных пользователем с правами на создание ролей.

2. Создайте пользователя и выдайте ему права на чтение:

   ```bash
   CREATE USER trino_reader WITH PASSWORD '<password>';
   GRANT CONNECT ON DATABASE <source_database> TO trino_reader;
   GRANT USAGE ON SCHEMA public TO trino_reader;
   GRANT SELECT ON ALL TABLES IN SCHEMA public TO trino_reader;
   ```

   Укажите:

   * `<password>` — пароль пользователя;
   * `<source_database>` — имя исходной базы данных.

   Если вы переносите несколько схем, выдайте привилегии `USAGE` и `SELECT` на каждую схему.

3. Разрешите подключение с внешнего IP-адреса облачного роутера — добавьте в файл `pg_hba.conf` строку:

   ```bash
   host <source_database> trino_reader <router_ip>/32 scram-sha-256
   ```

   Укажите:

   * `<source_database>` — имя исходной базы данных;
   * `<router_ip>` — внешний IP-адрес облачного роутера, который вы скопировали на шаге 1.

   Если на сервере используется метод аутентификации md5, укажите его вместо `scram-sha-256`.

4. Убедитесь, что PostgreSQL принимает подключения на внешнем интерфейсе: в файле `postgresql.conf` значение параметра `listen_addresses` должно содержать публичный IP-адрес сервера или '\*'. Изменение параметра `listen_addresses` применяется только после перезапуска PostgreSQL.

5. Примените изменения в файле `pg_hba.conf`:

   ```bash
   SELECT pg_reload_conf();
   ```

6. В файрволе сервера или в группах безопасности облачного провайдера разрешите входящие подключения на порт PostgreSQL (по умолчанию — 5432) с внешнего IP-адреса облачного роутера.

### 3. Создать кластер облачной базы данных PostgreSQL

Целевая база — это кластер облачных баз данных PostgreSQL в той же приватной подсети, что и кластер Trino.

1. [Создайте кластер PostgreSQL](/managed-databases/postgresql/create-cluster.mdx#create-cluster) с именем pg-target. При создании кластера:

   * выберите локацию — пул ru-7;
   * выберите версию PostgreSQL не ниже версии исходной базы данных;
   * в блоке Сеть выберите подсеть сети trino-migration-net;
   * выберите конфигурацию нод с размером диска с запасом относительно объема переносимых данных.

2. Дождитесь, пока кластер будет создан.

3. [Создайте пользователя](/managed-databases/postgresql/manage-users.mdx#create-user) trino_writer. Сохраните пароль — в панели управления он храниться не будет.

4. [Создайте базу данных](/managed-databases/postgresql/create-cluster.mdx#create-database) и выберите пользователя-владельца — trino_writer. Владелец базы данных может создавать в ней схемы и таблицы — это нужно Trino для записи данных. В PostgreSQL 15 и выше пользователь, который не является владельцем базы данных, по умолчанию получает только привилегию CONNECT.

5. Скопируйте DNS-адрес мастер-ноды. Можно посмотреть в [панели управления](https://my.selectel.ru/vpc/default/dbaas/): в верхнем меню нажмите **Продукты** → **Облачные базы данных** → вкладка **Активные** → страница кластера → вкладка **Подключение** → блок **Адреса для подключения**. Для DNS-адресов используется механизм master discovery — адрес привязан к роли ноды и не изменится, если мастером станет реплика.

**Важно**: Если у вас уже есть кластер облачных баз данных в другом регионе вы можете добавить [публичный доступ](/managed-databases/postgresql/public-ip.mdx) и использовать временно его для миграции.

Для подключения Trino к кластеру используйте [порт](/managed-databases/postgresql/connect-to-cluster.mdx#connection-ports) 5432 — прямое подключение к PostgreSQL. Порт 5433 ведет через пулер соединений: JDBC-драйвер, через который работает Trino, использует подготовленные выражения (prepared statements), а в режиме пулинга transaction они могут приводить к ошибкам.

### 4. Создать кластер Trino с каталогами

Для миграции нужны два [каталога](/cloud-for-trino/manage/catalogs.mdx) с коннектором PostgreSQL: pg_source — для исходной базы данных и pg_target — для целевой. Каталоги можно добавить при создании кластера или [после создания](/cloud-for-trino/manage/catalogs.mdx#add-catalog-in-existing-cluster).

1. В [панели управления](https://my.selectel.ru/data-platform/default/trino/) в верхнем меню нажмите Продукты и выберите Trino.

2. Нажмите **Создать кластер**.

3. Введите имя кластера — trino-migration.

4. Выберите локацию — пул ru-7. После создания кластера локацию изменить нельзя.

5. Выберите [версию Trino](/cloud-for-trino/about/about-cloud-for-trino.mdx#versions). После создания кластера версию изменить нельзя.

6. В блоке **Конфигурация** выберите конфигурации координатора и воркеров и количество воркеров. Воркеры читают и записывают данные, поэтому для переноса больших таблиц выбирайте более производительные конфигурации. Подробнее в подразделе [Конфигурация](/cloud-for-trino/create-cluster.mdx#configuration) инструкции Создать кластер Trino.

7. В блоке **Сеть**:

   7.1. В поле **Подсеть** выберите подсеть сети trino-migration-net — ту же, в которой находится кластер pg-target. После создания кластера подсеть изменить нельзя.

   7.2. Отметьте чекбокс **Внешний доступ к графическому интерфейсу**, чтобы подключаться к Trino со своего компьютера через интернет.

8. В блоке **Пароль администратора** введите пароль или нажмите **Сгенерировать**. Скопируйте и сохраните пароль — его нельзя будет посмотреть в панели управления, но можно [изменить](/cloud-for-trino/manage/change-administrator-password.mdx).

9. В блоке **Каталоги** добавьте каталоги `pg_source` и `pg_target`. Для каждого каталога:

   9.1. Нажмите **Добавить**.

   9.2. Введите имя каталога. Имя может содержать только строчные латинские буквы, цифры и нижнее подчеркивание, не более 63 символов.

   9.3. Выберите тип коннектора — PostgreSql.

   9.4. Введите параметры подключения из таблицы ниже.

   9.5. Нажмите **Добавить**.

10. Проверьте цену кластера.

11. Нажмите **Создать кластер**.

<CustomTable>
  <table>
    <tbody>
      <tr>
        <th>Параметр</th>
        <th>Каталог pg_source</th>
        <th>Каталог pg_target</th>
      </tr>

      <tr>
        <td>DNS-адрес или IP-адрес</td>
        <td>Публичный адрес исходной базы данных</td>
        <td>DNS-адрес мастер-ноды кластера pg-target</td>
      </tr>

      <tr>
        <td>Порт</td>
        <td>Порт исходной базы данных, обычно 5432 </td>
        <td> 5432 </td>
      </tr>

      <tr>
        <td>Имя базы данных</td>
        <td>Имя исходной базы данных</td>
        <td>Имя базы данных, которую вы создали на шаге 3</td>
      </tr>

      <tr>
        <td>Имя пользователя</td>
        <td> trino_reader </td>
        <td> trino_writer </td>
      </tr>

      <tr>
        <td>Пароль</td>
        <td>Пароль пользователя trino_reader </td>
        <td>Пароль пользователя trino_writer </td>
      </tr>
    </tbody>
  </table>
</CustomTable>

В SQL-запросах имя каталога — первая часть полного имени таблицы: `<catalog>.<schema>.<table>`.

### 5. Подключиться к кластеру Trino и проверить каталоги

К кластеру Trino подключается пользователь admin с паролем администратора, который вы задали при создании кластера. Подробнее о способах подключения в инструкции [Подключиться к кластеру Trino](/cloud-for-trino/manage/connect-to-cluster.mdx).

#### Через Trino CLI

1. Откройте CLI.

2. Подключитесь к кластеру:

   ```bash
   ./trino --server https://<trino_address> --user admin --password
   ```

   Укажите `<trino_address>` — адрес кластера Trino для подключения из интернета. Можно посмотреть в [панели управления](https://my.selectel.ru/data-platform/default/trino/): в верхнем меню нажмите **Продукты** → **Trino** → страница кластера → вкладка **Подключение**.

3. Введите пароль администратора.

#### Через DBeaver

1. Откройте DBeaver.

2. В верхнем меню нажмите **База данных** → **Новое соединение**.

3. Выберите Trino и нажмите **Далее**.

4. В поле **Хост** введите `<trino_address>` без https:// — адрес кластера Trino для подключения из интернета.

5. В поле **Порт** введите `443`.

6. Введите имя пользователя — admin и пароль администратора.

7. Откройте вкладку **Свойства драйвера** и для свойства SSL укажите значение **true**.

8. Нажмите **Тест соединения**, затем **Готово**.

#### Проверьте каталоги

Выполните запросы в Trino CLI или в редакторе SQL DBeaver:

```bash
SHOW CATALOGS;
SHOW SCHEMAS FROM pg_source;
SHOW TABLES FROM pg_source.public;
SHOW SCHEMAS FROM pg_target;
```

В списке каталогов должны быть `pg_source` и `pg_target`, а в схеме `pg_source.public` — таблицы исходной базы данных.

Если запрос к каталогу `pg_source` завершается ошибкой подключения, проверьте, что подсеть кластера подключена к облачному роутеру, а внешний IP-адрес роутера разрешен в файле `pg_hba.conf` и в файрволе сервера исходной базы данных.

### 6. Перенести данные

Optional: настройте сопоставление типов данных.

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

```bash
SET SESSION pg_source.array_mapping = 'AS_ARRAY';
SET SESSION pg_source.unsupported_type_handling = 'CONVERT_TO_VARCHAR';
```

Значение AS_ARRAY переносит массивы фиксированной размерности, для массивов произвольной размерности используйте значение AS_JSON. Значение CONVERT_TO_VARCHAR переносит столбцы с неподдерживаемыми типами как текст. Подробнее в разделе [Type mapping](https://trino.io/docs/current/connector/postgresql.html#type-mapping) документации Trino.

#### Вариант 1. SQL-запросы

1. Если вы переносите схему, отличную от public, создайте ее в целевой базе данных:

   ```bash
   CREATE SCHEMA IF NOT EXISTS pg_target.<schema>;
   ```

   Укажите `<schema>` — имя схемы.

2. Перенесите таблицу:

   ```bash
   CREATE TABLE pg_target.public.users AS
   SELECT * FROM pg_source.public.users;
   ```

   Trino создаст таблицу в целевой базе данных и вернет количество записанных строк. Повторите запрос для каждой таблицы.

3. Optional: чтобы перенести часть данных или изменить их при переносе, добавьте в запрос фильтры и выражения. Например:

   ```bash
   CREATE TABLE pg_target.public.users_2025 AS
   SELECT id, lower(email) AS email, created_at
   FROM pg_source.public.users
   WHERE created_at >= TIMESTAMP '2025-01-01 00:00:00';
   ```

4. Optional: чтобы догрузить строки, которые появились в исходной базе после переноса, используйте INSERT:

   ```bash
   INSERT INTO pg_target.public.users
   SELECT * FROM pg_source.public.users
   WHERE id > (SELECT coalesce(max(id), 0) FROM pg_target.public.users);
   ```

   Запрос подходит для таблиц, в которые строки только добавляются с возрастающим id. Изменения и удаления строк в исходной базе данных так не переносятся.

### 7. Проверить результат

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

   ```bash
   SHOW TABLES FROM pg_target.public;
   ```

2. Сравните количество строк в исходной и целевой таблицах:

   ```bash
   SELECT
     (SELECT count(*) FROM pg_source.public.users) AS source_rows,
     (SELECT count(*) FROM pg_target.public.users) AS target_rows;
   ```

3. Сравните столбцы: выполните запрос SHOW COLUMNS FROM pg_target.public.users; и сверьте результат со структурой таблицы в исходной базе данных — например, с выводом команды \d public.users в psql. Сравнивайте со структурой в исходной базе данных напрямую: столбцы, которые Trino пропустил, не видны и в каталоге pg_source.

4. **Optional**: найдите строки исходной таблицы, которых нет в целевой:

   ```bash
   SELECT * FROM pg_source.public.users
   EXCEPT
   SELECT * FROM pg_target.public.users;
   ```

   Пустой результат означает, что все строки перенесены. На больших таблицах запрос создает заметную нагрузку на обе базы данных. Столбцы типа json в EXCEPT сравнить нельзя — перечислите столбцы явно или ограничьтесь сравнением количества строк.

## Ограничения

Trino переносит данные, но не объекты базы данных. Запрос CREATE TABLE ... AS SELECT создает таблицу только со столбцами и строками — без первичных и внешних ключей, индексов, ограничений, значений по умолчанию, последовательностей, триггеров и функций.

* ключи и индексы. Создайте их после переноса нативными запросами PostgreSQL через процедуру system.execute:

  ```bash
  CALL pg_target.system.execute(query => 'ALTER TABLE public.users ADD PRIMARY KEY (id)');
  ```

  Также можно заранее создать структуру таблиц в целевой базе данных из вывода pg_dump --schema-only и переносить данные запросом INSERT INTO ... SELECT вместо CREATE TABLE ... AS SELECT;
* последовательности. Столбец типа serial переносится как integer без значения по умолчанию. Если приложение добавляет строки без id, создайте последовательность и установите ее значение больше максимального id;
* типы данных. Типы столбцов в целевой базе данных могут отличаться от исходных: например, json записывается как jsonb. Массивы и неподдерживаемые типы по умолчанию пропускаются — как их перенести, см. шаг 6;
* представления. Запрос SHOW TABLES показывает и таблицы, и представления. Из представления запрос CREATE TABLE ... AS SELECT создаст обычную таблицу с данными на момент переноса;
* согласованность данных. Каждая таблица читается в свой момент времени. Чтобы данные в целевой базе были согласованы, остановите запись в исходную базу на время переноса или догрузите новые строки перед переключением приложения;
* место на диске. При выполнении INSERT Trino сначала записывает данные во временную таблицу, а затем переносит их в целевую. На время загрузки на диске кластера pg-target нужен запас примерно на объем добавляемых данных;
* большие таблицы. Коннектор PostgreSQL читает каждую таблицу одним запросом, поэтому скорость переноса одной большой таблицы ограничена каналом до исходной базы данных и производительностью баз данных. Разбейте большую таблицу на части по диапазонам ключа и выполните несколько запросов INSERT INTO ... SELECT ... WHERE id BETWEEN ... параллельно.

## После миграции

1. Переключите приложение на кластер pg-target — подробнее в инструкции [Подключиться к кластеру PostgreSQL](/managed-databases/postgresql/connect-to-cluster/). Для доступа к кластеру из интернета [подключите публичный плавающий IP-адрес](/managed-databases/postgresql/public-ip.mdx).

2. В исходной базе данных удалите пользователя `trino_reader` и строку для него в файле `pg_hba.conf`, закройте в файрволе доступ с IP-адреса облачного роутера.

3. Если кластер Trino больше не нужен, удалите его или [отключите внешний доступ](/cloud-for-trino/manage/connect-to-cluster.mdx#disable-external-access). Если кластер остается для аналитики, [удалите каталог](/cloud-for-trino/manage/catalogs.mdx#delete-catalog) pg_source.
