Skip to content

Latest commit

 

History

History
245 lines (208 loc) · 20.2 KB

README-ru.md

File metadata and controls

245 lines (208 loc) · 20.2 KB

Импорт данных из источников JDBC в базы данных YDB

Эта утилита реализует импорт структуры таблиц и содержащихся в таблицах записей из источников JDBC в базы данных YDB.

На текущий момент протестирована работа утилиты со следующими видами источников данных:

Непротестированные источники данных JDBC с определенной вероятностью также могут оказаться поддержаны утилитой, поскольку в ней используются стандартные API для доступа к данным и метаданным.

Некоторые типы данных и виды табличных структур не поддерживаются, включая:

  • вложенные таблицы Oracle Database,
  • пространственные типы данных Microsoft SQL Server,
  • все объектные типы данных Informix.

1. Порядок использования утилиты импорта

При запуске утилита считывает настройки из файла в формате XML, указанного в качестве аргумента командной строки. В настройках указывается:

  • тип БД-источника и параметры подключения к источнику;
  • параметры подключения к БД-получателю YDB;
  • имя файла для сохранения YQL скрипта со структурой таблиц для YDB;
  • правила отбора таблиц для импорта из БД-источника;
  • перечень явно указанных SQL запросов на выборку данных из БД-источника (может использоваться для импорта результата запроса вместо конкретных таблиц);
  • правила формирования имён импортируемых таблиц в БД-получателе;
  • степень параллелизма операций (размер пула рабочих потоков, количество соединений с источником и получателем).

Импорт данных осуществляется в следующем порядке:

  1. Утилита подключается к БД-источнику, и определяет состав таблиц и SQL-запросов для импорта.
  2. Производится формирование структуры целевых таблиц YDB, которые опционально могут быть сохранены в виде YQL-скрипта.
  3. Над БД-получателем производится проверка наличия там целевых таблиц, с созданием недостающих таблиц и с опциональным их пересозданием уже существующих таблиц.
  4. Осуществляется импорт данных путём чтения из БД-источника с помощью SQL-запроса и вставки в БД-получатель YDB с помощью механизма Bulk Upsert.

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

2. Запуск утилиты

После сборки утилита доступна в виде ZIP-архива, в котором представлены примеры файлов настроек, пример скрипта запуска и набор архивов lib/*.jar, содержащих собственно исполняемый код утилиты и её зависимости, включая YDB SDK для Java.

Перед запуском утилиты необходимые драйверы JDBC следует также разместить в виде файлов *.jar в подкаталоге lib каталога инсталляции утилиты.

Также необходимо подготовить файл настроек на основе представленных примеров.

Пример команды запуска утилиты приведён в файле ydb-importer.sh, который и можно использовать для запуска, как показано ниже:

./ydb-importer.sh my-import-config.xml

Имя файла настроек указывается в параметре командной строки при запуске утилиты импорта.

3. Таблицы без первичного ключа

В каждой таблице YDB должен быть определён первичный ключ. При наличии у исходной таблицы первичного ключа (или, как минимум, уникального индекса) утилита импорта создаёт первичный ключ для соответствующей таблицы YDB с теми же колонками и в том же порядке, что и у исходной таблицы. При отсутствии первичного ключа и наличии нескольких уникальных индексов утилита выбирает индекс с минимальным количеством используемых колонок.

В случае отсутствия в исходной таблице явно определённого первичного ключа состав его колонок можно определить явным образом в настройках импорта соответствующей таблицы в виде элементов key-column раздела table-ref (см. далее пример в разделе с описанием формата файла настроек).

Если первичный ключ явно не указан в настройках, и отсутствует в определении исходной таблицы в БД-источнике, то утилита импорта автоматически добавляет в целевую таблицу колонку ydb_synth_key и создаёт первичный ключ на её основе. Значения колонки синтетического ключа вычисляются как хеш-код по алгоритму "SHA-256" над всеми значениями всех колонок строки таблицы, за исключением колонок типа BLOB.

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

4. Импорт данных BLOB

Для каждого поля BLOB на источнике создаётся дополнительная таблица YDB следующей структуры:

CREATE TABLE `blob_table`(
    `id` Int64,
    `pos` Int32,
    `val` String,
    PRIMARY KEY(`id`, `pos`)
)

Формат имени дополнительной таблицы определяется настройкой table-options / blob-name-format.

Данные из исходного BLOB-поля сохраняются в виде последовательности записей созданной дополнительной таблицы. Для каждого исходного BLOB-значения генерируется уникальное число, хранимое в поле id. Ссылка на значение сохраняется в основной таблице в поле, имя которого соответствует имени исходного BLOB-поля. Каждая запись хранит не более 64 Кбайт данных в поле val, последовательность блоков данных определяется значением поля pos.

Для PostgreSQL работа с данными BLOB в варианте EXTENSION lo может требовать явного предоставления специальных полномочий для учётной записи, используемой для подключения к БД-источнику. Альтернативный вариант - установка режима совместимости на уровне базы данных PostgreSQL:

ALTER DATABASE dbname SET lo_compat_privileges TO on;

5. Формат файла настроек

Примеры файлов настроек с комментариями:

Описание формата файла настроек:

<?xml version="1.0" encoding="UTF-8"?>
<ydb-importer>
    <workers>
        <!-- Количество рабочих потоков (целое число от 1 и выше).
             Также соответствует максимальному устанавливаемому количеству соединений с источником,
             и максимальному количеству сессий с получателем.
         -->
        <pool size="4"/>
    </workers>
    <!-- Параметры подключения к БД-источнику.
         type - обязательный атрибут, влияющий на логику взаимодействия с источником
      -->
    <source type="generic|postgresql|mysql|oracle|mssql|db2|informix">
        <!-- Имя основного класса драйвера JDBC. Типичные значения:
              org.postgresql.Driver
              com.mysql.cj.jdbc.Driver
              org.mariadb.jdbc.Driver
              oracle.jdbc.driver.OracleDriver
              com.microsoft.sqlserver.jdbc.SQLServerDriver
              com.ibm.db2.jcc.DB2Driver
              com.informix.jdbc.IfxDriver
        -->
        <jdbc-class>driver-class-name</jdbc-class>
        <!-- URL JDBC для подключения к источнику. Примеры значений:
              jdbc:postgresql://hostname:5432/dbname
              jdbc:mysql://hostname:3306/dbname
              jdbc:mariadb://hostname:3306/dbname
              jdbc:oracle:thin:@//hostname:1521/serviceName
              jdbc:sqlserver://localhost;encrypt=true;trustServerCertificate=true;database=AdventureWorks2022;
              jdbc:db2://localhost:50000/SAMPLE
              jdbc:informix-sqli://localhost:9088/stores_demo:INFORMIXSERVER=informix
        -->
        <jdbc-url>jdbc-url</jdbc-url>
        <username>username</username>
        <password>password</password>
    </source>
    <!-- Параметры подключения к БД-получателю. -->
    <target type="ydb">
        <!-- Выгрузить скрипт создания таблиц для YDB в указанный файл. 
             Может использоваться в том числе при отсутствии указания
             connection-string для генерации схемы без фактического создания
             таблиц.  -->
        <script-file>sample-database.yql.tmp</script-file>
        <!-- Строка подключения: protocol + endpoint + database. Примеры значений:
            grpcs://ydb.serverless.yandexcloud.net:2135?database=/ru-central1/b1gfvslmokutuvt2g019/etn63999hrinbapmef6g
            grpcs://localhost:2135?database=/local
            grpc://localhost:2136?database=/Root/testdb
         -->
        <connection-string>ydb-connection-string</connection-string>
        <!-- Режим аутентификации: 
            ENV      использование переменных окружения для настройки аутентификации
            NONE     анонимное подключение к БД - не для продуктивных систем
            STATIC   аутентификация по логину и паролю
            SAKEY    Аутентификация по ключу сервисного аккаунта (управляемый сервис YDB)
            METADATA Аутентификация по метаданным виртуальной машины облака (управляемый сервис YDB)
        -->
        <auth-mode>ENV</auth-mode>
        <!-- 
            В режиме ENV данные аутентификации необходимо установить в переменных окружения,
            как описано в документации: https://ydb.tech/ru/docs/reference/ydb-sdk/auth#env
            Если аутентификация по ключу сервисного аккаунта (явно либо через указание переменной
            окружения YDB_SERVICE_ACCOUNT_KEY_FILE_CREDENTIALS), то файл ключа надо
            генерировать как написано здесь:
            https://cloud.yandex.ru/docs/iam/operations/authorized-key/create
        -->
        <!-- Логин и пароль для auth-mode: STATIC -->
        <static-login>username</static-login>
        <static-password>password</static-password>
        <!-- Удалять ли уже существующие таблицы с теми же именами, что предполагается заливать -->
        <replace-existing>true</replace-existing>
        <!-- Заливать ли данные в таблицы после их создания или пересоздания -->
        <load-data>true</load-data>
        <!-- Максимальная порция заливки обычных данных, в строках -->
        <max-batch-rows>1000</max-batch-rows>
        <!-- Максимальная порция заливки BLOB-данных, в строках -->
        <max-blob-rows>200</max-blob-rows>
    </target>
    <!-- Настройки преобразования структуры исходных таблиц.
         Устанавливаются централизованно с присвоением имени,
         затем используются для конкретной группы отбираемых таблиц.   -->
    <table-options name="default">
        <!--  Возможные значения case-mode: ASIS (по умолчанию), LOWER, UPPER.
              Влияет на регистр подставляемых в шаблоны имён.  -->
        <case-mode>ASIS</case-mode>
        <!-- Шаблон полного имени таблицы, включая каталог размещения.
             Используются подстановочные имена ${schema} и ${table},
             соответствующие схеме и имени копируемой исходной таблицы. -->
        <table-name-format>oraimp1/${schema}/${table}</table-name-format>
        <!-- Шаблон полного имени таблицы, включая каталог размещения.
             Используются подстановочные имена ${schema}, ${table} и ${field},
             соответствующие схеме, имени копируемой исходной таблицы и имени
             поля типа BLOB. -->
        <blob-name-format>oraimp1/${schema}/${table}_${field}</blob-name-format>
        <!-- Возможные значения: DATE (по умолчанию), INT, STR.
             Вариант DATE не позволяет сохранить даты ранее 1 января 1970 года.
             Вариант INT хранит дату как 32-битное целое в формате ГГГГММДД.
             Вариант STR хранит дату как строку в формате ГГГГ-ММ-ДД.
         -->
        <conv-date>INT</conv-date>
        <conv-timestamp>STR</conv-timestamp>
        <!-- Если указано значение true, колонки таблиц неподдерживаемых типов пропускаются
             с выводов в лог соответствующего предупреждения. В противном случае генерируется
             ошибка импорта, и соответствующая таблица пропускается целиком. -->
        <skip-unknown-types>true</skip-unknown-types>
    </table-options>
    <!-- Фильтр для отбора копируемых таблиц с источника -->
    <table-map options="default">
        <!-- Включаемые схемы -->
        <include-schemas regexp="true">.*</include-schemas>
        <!-- Исключаемые схемы -->
        <exclude-schemas>SOMESCHEMA</exclude-schemas>
        <!-- Также могут присутствовать include-tables и exclude-tables, 
             для явного указания фильтра по именам таблиц
             и/или регулярным выражениям над именами таблиц. -->
    </table-map>
    <!-- Конкретный запрос или указание ссылки на конкретную таблицу -->
    <table-ref options="default">
        <schema-name>ora$sys</schema-name>
        <table-name>all_tables</table-name>
        <!-- Если указан запрос, он выполняется как написано -->
        <query-text>SELECT * FROM all_tables</query-text>
        <!-- Для запроса желательно явно определить ключевые колонки.  -->
        <key-column>OWNER</key-column>
        <key-column>TABLE_NAME</key-column>
    </table-ref>
</ydb-importer>

6. Сборка из исходных кодов

Требуется Java 8 или выше. Требуется Maven (сборка проверялась на версии 3.8.6).

Для формирования пакета с утилитой необходимо выполнить команду в каталоге с исходным кодом:

mvn package

В результате в подкаталоге target будет создан файл ydb-importer-X.Y-SNAPSHOT-bin.zip, где X.Y - номер версии утилиты.