Перейти к содержанию

Synapse

В данном разделе приведены сведения о Synapse, плагине для СУБД Picodata.

Picodata Enterprise

Функциональность плагина доступна только в коммерческой версии Picodata.

Общие сведения

Основная задача Synapse ("Синапса") — предоставить пользователям инструмент миграции с кластера проприетарной СУБД Oracle (например, Oracle Exadata) на кластер PostgreSQL, использующий открытое (open source) программное обеспечение.

Synapse позволяет переносить данные из одного кластера в другой без их остановки. Для этого в плагине реализованы следующие модули:

  • начальный перенос данных
  • перенос и синхронизация изменений (Change Data Capture, CDC)

Оба модуля могут работать параллельно. Консистентное состояние целевого кластера PostgreSQL будет достигнуто не ранее чем отработает модуль начального переноса данных.

Схема переноса

Перенос данных из Oracle в PostgreSQL происходит при помощи посредничества Picodata и Synapse. Кластер Picodata с плагином Synapse выступает в роли промежуточного звена, транслируя через себя данные из Oracle в PostgreSQL. Схема переноса данных показана ниже.

SYNAPSE GENERAL SCHEME

Для переноса данных требуется выполнить следующие условия:

  • на стороне Oracle предварительно нужно настроить внешний XStream (XStream Out) — API-интерфейс для взаимодействия с внешними системами. Это специальный механизм Oracle, с помощью которого можно получать события об изменении состояния данных в порядке очереди
  • на стороне PostgreSQL создать таблицы, в которые требуется перенести данные из Oracle. Они не обязательно должны повторять схему в Oracle
  • подготовить YAML-файл конфигурации для Synapse с настройками подключения и шардирования целевых таблиц и сопоставлением структуры данных Oracle в структуру данных Postgres

Подробности реализации

Каждый экземпляр Synapse может работать только с одним подключением по Xstream и транслировать данные только в один кластер PostgreSQL. С помощью Xstream можно перенести таблицу или несколько таблиц, причем как с активного инстанса Oracle, так и с его реплики.

На принимающем кластере PostgreSQL должны быть заранее созданы таблицы с совместимым набором колонок (число колонок и тип их данных должны подходить к исходным таблицам). Если кластер PostgreSQL шардирован, то Synapse должен знать ключ распределения для каждой из таблиц. Если требуется трансляция данных в несколько кластеров PostgreSQL, то потребуется соответственное количество инстансов Picodata с плагином Synapse. Это отражено на схеме ниже.

SYNAPSE DETAILED SCHEME

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

При сбое соединения активные транзакции откатываются; в дальнейшем они повторяются заново без нарушения консистентности и потери данных (благодаря идемпотентности DML-операций, которые Synapse использует для сохранения данных в Postgres).

Synapse разумно потребляет вычислительные и сетевые ресурсы: если скорость записи в целевой кластер PostgreSQL недостаточна для синхронизации изменений в реальном времени, то Synapse снижает скорость чтения. Наибольшая производительность достигается в тех случаях, когда данные на целевом кластере распределяются равномерно между узлами (шардами).

Конфигурация Synapse

Структура файла конфигурации

Конфигурация Synapse хранится в YAML-файле и состоит из следующих основных блоков:

  • настройки подключения к Oracle:
    • имя, хост и порт инстанса
    • настройки подключения к Xstream
    • настройки подключения к БД Oracle
  • настройки подключения к кластеру PostgreSQL:
    • настройки подключения к каждому из шардов кластера
  • соотношения таблиц между кластерами
Пример конфигурации с описанием полей
runtime: # Настройки tokio-рантайма.
  name: "sistokio"
  worker_threads: 2

bridges:
  test: # Название моста, используется в логах.
    oracle:
      name: "test" # Название соединения, используется в логах.
      host: "127.0.0.1" # Адрес сервера, может быть dns или ip.
      port: 1521 # Порт.
      xstream_db: "TNT" # Название БД (service name), в которой создан xstream.
      xstream_name: "tntsync" # Название xstream.
      xstream_username: "c##xstrmadmin" # Имя пользователя, у которого есть права на подключение к xstream и захвату изменений из него.
      xstream_password: "xstrmadmin" # Пароль пользователя выше.
      init_db: "TNTPDB" # База данных, из которой необходимо забирать начальные данные.
      init_enabled: true # Включен или выключен модуль начального наполнения данных.
      init_username: "PDBADMIN" # Имя пользователя для чтения данных из базы.
      init_password: "tntPswd" # Пароль пользователя выше.
      connect_tries: 2 # Сколько попыток подключения делать перед тем, как инициализация плагина будет признана неуспешной.

    postgres:
      name: "test" # Название соединения, используется в логах.
      shards: # Если PostgreSQL не шардирован, укажите 1 шард ниже. Для успешной инициализации плагина необходимо подключение ко всем шардам.
        - host: "127.0.0.1" # Адрес шарда.
          port: 5431 # Port шарда.
          user: "postgres" # Имя пользователя для записи данных в шард.
          password: "tntPswd" # Пароль пользователя выше.
          db: "postgres" # Название БД, в которую пишутся данные.
          pool_size: 2 # Размер пул потоков.
          connect_tries: 2 # Сколько попыток подключения делать перед тем, как инициализация плагина будет признана неуспешной.

        - host: "127.0.0.1"
          port: 5433
          user: "postgres"
          password: "tntPswd"
          db: "postgres"
          pool_size: 2
          connect_tries: 2

    tables: # Настройка маппинга таблиц и колонок. Изменения в данных таблиц, не описанных ниже, будут проигнорированы.
      pdbadmin.deal: # Полное имя таблицы в Oracle.
        pk: ["id"] # Первичный ключ, может быть составным.
        name: "public.deal" # Полное имя таблицы в PostgreSQL.
        bindings: # Маппинг колонок в формате: <название колонки в Oracle> : [ "<название колонки в PostgreSQL>", "<тип данных в колонке>"" ].
          id: ["id", "int"]
          person_id: ["person_id", "int"]
          deal_number: ["deal_number", "text"]
          amount: ["amount", "decimal"]

      pdbadmin.person:
        pk: ["id"]
        name: "public.person"
        bindings:
          id: ["id", "int"]
          age: ["age", "int"]
          salary: ["salary", "decimal"]
          fullname: ["fullname", "text"]

Расположение файла конфигурации задается переменной SYNAPSE_CONFIG. Например:

$ echo $SYNAPSE_CONFIG
configs/config.cluster.yml

Сопоставление колонок в таблицах

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

Семейство типов значения в Oracle Тип в PostgreSQL Значение для файла конфигурации
string TEXT text
binary BYTE byte
binary BYTEA bytea
number INTEGER int
number BIGINT bigint
number SMALLINT smallint
number decimal decimal
date DATE date
date TIMESTAMP timestamp
date TIMESTAMPTZ timestamptz
date with time DATE date
date with time TIMESTAMP timestamp
date with time TIMESTAMPTZ timestamptz
date with time and TZ DATE date
date with time and TZ TIMESTAMP timestamp
date with time and TZ TIMESTAMPTZ timestamptz

Правила применения:

  • XStream не присылает конкретный тип значения, только семейство типов
  • В файле конфигурации следует указать значение (из третьей колонки таблицы выше), опираясь на семейство типов колонки в Oracle (первая колонка) и желаемый тип в PostgreSQL (вторая колонка)
  • Если в конфигурации указаны smallint, int, bigint, то Synapse проверит, что число является целым и помещается в указанный тип
  • При конвертации date -> timestamp Synapse выставит время в 00:00
  • При конвертации date -> timestamptz Synapse считает, что исходное значение в UTC. При этом, он сначала выставит время в 00:00, затем сделаетtimezoneoffset в 0 секунд
  • При конвертации date with time -> timestamptz Synapse считает, что исходное значение в UTC, и выставляет timezoneoffset в 0 секунд.
  • При конвертации date with time and TZ -> timestamp Synapse конвертирует время в UTC
  • При конвертации date with time and TZ -> date Synapse сначала конвертирует время в UTC, а потом берет от результата дату
  • Значение NULL считается валидным для любой пары конвертации
  • Любая другая пара (тип данных в Oracle, желаемый тип в PostgreSQL) приведет к ошибке и останову Synapse.

Запуск Synapse

Для запуска Synapse следует выполнить команду picodata run со скриптом, который инициализирует плагин:

picodata run --script=init.lua

Образец файла init.lua находится в репозитории Synapse.