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

Synapse

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

Picodata Enterprise

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

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

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

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

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

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

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

SYNAPSE GENERAL SCHEME

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

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

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

SYNAPSE DETAILED SCHEME

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

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

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

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

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

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

Подключение плагина

Содержимое архива с плагином следует распаковать в любую удобную директорию, которую после этого нужно будет указать как PLUGIN_DIR для инстанса Picodata.

При запуске одного инстанса из командной строки директорию плагина можно указать с помощью параметра:

picodata run --plugin-dir=<PLUGIN-DIR> ...

Однако, для полноценной использования плагина рекомендуется запустить кластер с помощью роли Ansible.

После запуска Picodata с поддержкой плагинов в заданной директории подключитесь к административной консоли инстанса Picodata.

Установите плагин, добавьте его к тиру и включите его с помощью следующих SQL-команд:

CREATE PLUGIN synapse 1.0.0;
ALTER PLUGIN synapse 1.0.0 ADD SERVICE synapse TO TIER default;
ALTER PLUGIN synapse 1.0.0 ENABLE;

Для диагностики работы плагина обратитесь к отладочному журналу инстанса Picodata.

Проверка с помощью Ansible

Подготовка

  1. Изучите документацию по развертыванию кластера Picodata. Выполнить инструкции по установке роли.
  2. Скачайте нужную версию плагина synapse и положите пакет в рабочую директорию.
  3. Проверьте наличие конфигурационного файла для плагина synapse-config.yml, проверьте настройки в нем (см. ниже).

Примечание

На сервере, с которого будет происходить установка, необходим Ansible и доступ на серверы кластера с повышением привилегий.

Установка окружения

Создайте файл с описанием кластера согласно руководству по развертыванию кластера. Например, synapse.yml.

---
all:
  vars:
    user: username # имя пользователя, под которым будут запущены процессы picodata
    group: groupname # группа пользователя, под которой будут запущены процессы picodata
    password: "<password>"
    cluster_name: synapse
    audit: false
    log_level: warn
    log_to: file

    conf_dir: "/opt/picodata/etc"
    data_dir: "/opt/picodata/data"
    run_dir: "/var/run/picodata"
    log_dir: "/opt/picodata/logs"

    fd_uniq_per_instance: true

    purge: true # при очистке кластера удалять в том числе все данные и логи с сервера

    listen_ip: "{{ ansible_default_ipv4.address }}" # ip-адрес, который будет слушать инстанс, по умолчанию ansible_default_ipv4.address

    first_bin_port: 13301 # начальный бинарный порт для первого инстанса (он же main_peer)
    first_http_port: 18001
    first_pg_port: 15001

    init_system: "supervisord"
    rootless: true

    plugins:
      synapse:
        path: "synapse_1.0.0.tar.gz"
        tiers:
          - default
        config: "synapse-config.yml"
    tiers:
      default:
        instances_per_server: 5
        replication_factor: 15
        config:
          memtx:
            memory: 1G
          iproto:
            max_concurrent_messages: 1500
    admin_password: "<password>"
    property:
      auto_offline_timeout: 30
DC1: # Датацентр (failure_domain)
  hosts:
    hostname1:
      ansible_host: ip1
    hostname2:
      ansible_host: ip2
    hostname3:
      ansible_host: ip3

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

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

Семейство типов значения в 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-config.yml. Пример:

 bridges:
    test: # Название моста, используется в журналах.
      oracle:
        name: "test" # Название соединения, используется в журналах.
        host: "127.0.0.1" # Адрес сервера, может быть DNS или IP.
        port: 1521 # Номер порта.
        xstream_db: "TNT" # Название БД (service name), в которой создан Xstream.
        xstream_name: "tntsync" # Название Xtream.
        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 # Порт шарда.
            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"]

Подготовьте плейбук picodata.yml:

---
- name: Deploy Picodata cluster
  hosts: all
  become: true

  tasks:
    - name: Import picodata-ansible role
      ansible.builtin.import_role:
        name: picodata-ansible

В результате в рабочем каталоге должно быть 4 файла:

  • synapse.yml
  • picodata.yml
  • synapse_config.yml
  • synapse_1.0.0.tar.gz

Запустите раскатку Synapse:

ansible-playbook -i synapse.yml picodata.yml

См. также: