Как стать автором
Поиск
Написать публикацию
Обновить
221.17
Postgres Professional
Разработчик СУБД Postgres Pro

Как успешно мигрировать с Oracle на Postgres Pro Enterprise

Уровень сложностиСредний
Время на прочтение11 мин
Количество просмотров476

Миграция схемы и данных с БД Oracle на БД Postgres Pro Enterprise — тернистый путь, имеющий бесчисленное множество различных встречающихся по дороге тонкостей. Несмотря на свою сложность, этот путь упрощается благодаря расширенным возможностям Postgres Pro Enterprise, имитирующим механизмы СУБД Oracle, которых нет в «ванильной» версии.

В свою очередь, для автоматической миграции существует open-source-утилита ora2pg, однако она не поддерживает данные расширенные возможности Postgres Pro Enterprise. Именно поэтому нами была создана утилита ora2pgpro, ориентированная на миграцию с Oracle на Postgres Pro Enterprise с учётом особенностей последнего.

Рассмотрим, какие трудности должна превозмочь утилита автоматического портирования при миграции, почему open-source-решение ora2pg не может полностью удовлетворить все наши потребности при портировании и, наконец, что же это за зверь такой — ora2pgpro.

Препятствия на пути к миграции на «ванильную» СУБД PostgreSQL

Прежде всего нам необходимо понимать, а какие вообще объекты необходимо экспортировать. Очевидно, что нам нужно перенести абсолютно все объекты базы данных, на которых зиждется бизнес‑логика. Это могут быть таблицы, индексы, функции, написанные PL/SQL, автономные транзакции, пакеты, схемы и так далее. Также важно обеспечить, чтобы технологии целевой базы данных полностью соответствовали по функциональности технологиям исходной базы данных Oracle. В противном случае мы не сможем должным образом воспроизвести бизнес-логику исходной базы.

Как минимум в «ванильной» СУБД PostgreSQL нет реализации как таковых пакетов, автономных транзакций и других механизмов на уровне ядра (рисунок 1), что может сильно усложнить миграцию. В свою очередь, СУБД Postgres Pro Enterprise, как мы выясним далее, лишена данных недостатков.

Рисунок 1. Классификация конвертируемых объектов Oracle по наличию аналогов в «ванильном» PostgreSQL
Рисунок 1. Классификация конвертируемых объектов Oracle по наличию аналогов в «ванильном» PostgreSQL

Поскольку структура базы данных может описывать объёмную и витиеватую бизнес‑логику, ручная конвертация не является хорошим решением вследствие колоссальной траты времени. Поэтому создание автоматических конвертеров структуры БД, таких как ora2pg и ora2pgpro было лишь вопросом времени.

Что такое ora2pg и ora2pgpro

ora2pg — это свободно распространяемая утилита автоматической конвертации БД Oracle в схему PostgreSQL. Эта утилита обладает широкой функциональностью, позволяющей автоматизировать бо́льшую часть задач миграции структуры базы данных. ora2pg способна экспортировать самые разнообразные объекты базы данных, в том числе: таблицы, права пользователей, схемы, BLOB, PL/SQL-код и так далее. Утилита может проводить оценку стоимости миграции с целью определения объектов, которые невозможно преобразовать автоматически.

Миграция на ванильную PostgreSQL — это, конечно, очень хорошо, но что там насчёт миграции на Postgres Pro Enterprise? ora2pgpro — наша коммерческая версия open-source-утилиты ora2pg, учитывающая при миграции реализованную в СУБД Postgres Pro Enterprise функциональность, аналогичную СУБД Oracle.

Основные нововведения, отличающие ora2pgpro от своего собрата:

  1. Поддержка автономных транзакций Postgres Pro Enterprise.

  2. Поддержка пакетов Postgres Pro Enterprise.

  3. Поддержка ассоциативных массивов enterprise-версии утилиты pg_variables.

  4. Улучшенный алгоритм трансляции PL/SQL в PL/pgSQL.

Далее мы рассмотрим проблемы, возникающие при миграции с Oracle на PostgreSQL с помощью ora2pg, так и решения этих проблем при миграции с Oracle на Postgres Pro Enterprise с помощью ora2pgpro.

Поддержка автономных транзакций

Утилита ora2pg имитирует автономные транзакции, хоть и в «ванильной» версии их попросту нет, что не скажешь о Postgres Pro Enterprise. Автономные транзакции — это специальные подтранзакции, которые могут быть зафиксированы (COMMIT) или отменены (ROLLBACK) независимо от основной (родительской) транзакции. Это означает, что результат автономной транзакции (например, запись лога или аудит) становится видимым немедленно после её завершения, даже если родительская транзакция ещё продолжается или будет впоследствии отменена. Чтобы имитировать автономные транзакции с помощью dblink, необходимо запускать новые соединения, что непременно скажется на быстродействии СУБД. Имитация расширением pg_background ненамного лучше: для каждой автономной транзакции она запускает фоновые процессы, что также может влететь в копеечку в контексте скорости работы.

Подобные проблемы с «имитациями» подтолкнули нас к реализации автономных транзакций непосредственно в ядре Enterprise версии СУБД Postgres Pro, разработанная реализация работает значительно быстрее двух вышеописанных. Однако, как вы можете догадаться, утилита ora2pg не поддерживает такую реализацию.

 Рисунок 2. Соответствие реализаций автономных транзакций и их характеристик
Рисунок 2. Соответствие реализаций автономных транзакций и их характеристик

В свою очередь, утилита ora2pgpro способна экспортировать автономные транзакции напрямую в формате Postgres Pro. Для этого необходимо лишь задать параметру POSTGRESPRO_ATX значение 1.

Поддержка пакетов

Как мы знаем, в «ванильной» версии PostgreSQL в отличие от СУБД Oracle отсутствует реализация пакетов, что, в свою очередь, вставляет нам палки в колёса при миграции. К счастью, утилита ora2pg поддерживает экспорт пакетов СУБД Oracle несмотря на отсутствие реализации последних в «ванильной» PostgreSQL. Поддержка пакетов производится с помощью схем баз данных, а глобальные переменные, которые могут быть определены в пакете, реализуются посредством функций получения и изменения параметров конфигурации current_setting и set_config соответственно. Таким образом, для эмуляции пакетов — аналогично ситуации с автономными транзакциями — используются окольные пути. Однако такая имитация приносит заметные накладные расходы и, как правило, снижает производительность полученного кода; кроме того, из‑за расхождений семантики его работоспособность нередко оказывается нестабильной.

С целью упрощения миграции и избавления от многообразия «костыльных» решений в ядре Postgres Pro Enterprise создана эмуляция пакетов на основе схем с реализацией настоящих переменных пакетов и областей их видимости. Однако, к сожалению, утилита ora2pg не поддерживает соглашения о пакетах этой СУБД.

В свою же очередь, утилита ora2pgpro закрывает «прорехи» в функциональности open-source-версии, позволяя напрямую экспортировать пакеты Oracle как пакеты Postgres Pro. Чтобы включить этот режим, необходимо всего лишь при настройке задать для типа экспорта TYPE значение PACKAGE.

Тема эмуляции пакетов в Postgres Pro Enterprise является достаточно обширной и комплексной. Мы даём лишь высокоуровневый обзор. Для более детального и глубокого понимания механизмов, лежащих в основе этой эмуляции, включая управление глобальными переменными, областями видимости и жизненным циклом пакетов, настоятельно рекомендуем ознакомиться с подробной статьёй Игоря Мельникова, которая всесторонне раскрывает эту тему.

В общих чертах, эмуляция пакетов в Postgres Pro Enterprise достигается путём преобразования каждого пакета Oracle в отдельную схему PostgreSQL. Процедуры и функции пакета преобразуются в функции внутри соответствующей схемы, но с важными отличиями от подхода утилиты ora2pg. Во‑первых, ora2pgpro поддерживает автоматическую инициализацию пакетов через специальную функцию init(). Во‑вторых, поддерживает разделение на публичные и приватные методы пакетов. Данные особенности реализованы в Postgres Pro Enterprise на уровне ядра СУБД и подробно описаны в документации. Такой подход позволяет сохранить модульность и инкапсуляцию, присущие пакетам Oracle, обеспечивая при этом нативную и высокопроизводительную работу в среде Postgres Pro Enterprise. ora2pgpro автоматически выполняет все необходимые преобразования, чтобы исходный PL/SQL код пакетов Oracle был корректно транслирован в PL/pgSQL, использующий эту нативную эмуляцию.

Поддержка ассоциативных массивов

Аналогично ситуации с пакетами, в «ванильной» версии PostgreSQL отсутствуют индексированные коллекции, что усложняет миграцию с СУБД Oracle. Из‑за этого и утилита ora2pg нам не поможет: она не сможет должным образом интерпретировать коллекции.

Именно поэтому нами был создан модуль pg_variables, который в том числе реализует поддержку ассоциативных массивов. В свою очередь, ora2pgpro поддерживает экспортирование коллекций Oracle типа «ассоциативный массив» как коллекции утилиты pg_variables. Во время конвертации вызовы методов коллекций базы данных Oracle преобразуются в вызовы соответствующих функций расширения pg_variables, эмулирующих эти методы.

Например, установление значения для элемента ассоциативного массива в Oracle соответствует вызову функции pgv_set_elem расширения pg_variables. Аналогично метод удаления элемента Oracle заменяется на соответствующую функцию pgv_remove_elem. В свою очередь, метод проверки существования элемента с определённым ключом конвертируется в функцию pgv_exists_elem. На рисунке 3 проиллюстрированы описанные конвертации (ASSOC — название пакета, в котором определена коллекция).

 Рисунок 3. Соответствие операций СУБД Oracle и расширения pg_variables над коллекциями
Рисунок 3. Соответствие операций СУБД Oracle и расширения pg_variables над коллекциями

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

Поддержка VARRAY-массивов

Помимо ассоциативных массивов наша утилита ora2pgpro способна интерпретировать VARRAY-массивы. Open‑source утилита ora2pg часто испытывает трудности с корректной трансляцией конструкций с участием VARRAY, тогда как ora2pgpro справляется с ними благодаря глубокому синтаксическому анализу.

Рассмотрим пример трансляции VARRAY-массива при помощи ora2pgpro:

-- PL/SQL
 
TYPE r_customer_type IS RECORD (
customer_name VARCHAR2(50),
credit_limit NUMBER(10,2)
…
 
t_customers t_customer_type := t_customer_type();
…
 
t_customers.EXTEND;
 
t_customers(t_customers.LAST).customer_name := 'ABC Corp';
 
t_customers(t_customers.LAST).credit_limit := 10000;
 
tmp_string := 'The number of customers is ' || t_customers.COUNT;
-- PL/pgSQL
 
CREATE TYPE PKGC.r_customer_type AS (
customer_name varchar(50),
credit_limit numeric(10,2)
);
…
 
/*WARNING: collection constructors are not supported.*/
 
t_customers PKGC.t_customer_type /*:=*/ /*t_customer_type() /*WARNING: varray constructors are not supported.*/*/;
…
 
t_customers = array_cat(t_customers, array_fill(NULL::PKGC.R_CUSTOMER_TYPE, ARRAY[1]));
 
t_customers[array_upper(T_CUSTOMERS, 1)].customer_name = 'ABC Corp';
 
t_customers[array_upper(T_CUSTOMERS, 1)].credit_limit = 10000;
 
tmp_string = 'The number of customers is ' || array_length(T_CUSTOMERS, 1);

В этом примере мы видим объявление VARRAY t_customer_type, его инициализацию, использование метода EXTEND для добавления элементов, присвоение значений полям записи внутри VARRAY, а также использование LAST и COUNT. Утилита ora2pgpro способна корректно транслировать эти операции в эквивалентные конструкции PL/pgSQL, используя нативные возможности Postgres Pro Enterprise для работы с массивами и записями, или, при необходимости, функции pg_variables для более сложных сценариев. Вы, конечно, обратили внимание на то, что утилита ora2pgpro добавила комментарий с предупреждением. Она не просто подставляет новые конструкции вместо старых по шаблону, а проводит анализ исходного кода. Да, ora2pgpro действительно анализирует исходный код, работая по другому принципу, нежели свободно распространяемая ora2pg.

Продвинутый алгоритм трансляции PL/SQL в PL/pgSQL

Проблемы при миграции часто возникают также при конвертации PL/SQL кода в PL/pgSQL. Утилита ora2pg способна к подобной трансляции, однако реализация оставляет желать лучшего: конвертация происходит посредством примитивных Perl «регулярок». Вследствие «наивности» алгоритма экспортирования утилита ora2pg часто может некорректно транслировать PL/SQL-код. Однако утилита ora2pgpro лишена этого недостатка, поскольку она анализирует синтаксис и семантику PL/SQL-кода, умея транслировать более сложные конструкции.

Непосредственно алгоритм трансляции утилиты ora2pgpro разделён на несколько этапов (Рисунок 4). Сначала утилите необходимо найти и скачать PL/SQL-код из исходной базы данных Oracle, который необходимо экспортировать. Затем происходит обработка и создание абстрактного синтаксического дерева (AST) кода, которое, в свою очередь, преобразуется в соответствующий целевой код на языке PL/pgSQL. Если же сгенерированный код имеет фрагменты, которые не удалось сконвертировать, то утилита оставит WARNING сообщения в соответствующих местах. Впоследствии разработчику необходимо самостоятельно обработать данные фрагменты.

Рисунок 4. Алгоритм трансляции PL/SQL в PL/pgSQL
Рисунок 4. Алгоритм трансляции PL/SQL в PL/pgSQL

Этот подход к трансляции, основанный на анализе синтаксиса и семантики PL/SQL кода с построением абстрактного синтаксического дерева (AST), обеспечивает высокую точность конвертации. Это позволяет разработчикам ora2pgpro эффективно расширять поддержку новых конструкций и улучшать существующие преобразования в будущих версиях продукта. Важно отметить, что ora2pgpro является коммерческим продуктом и любые несанкционированные модификации его кода пользователями не допускаются и могут привести к нарушению условий лицензирования.

Также сто́ит уточнить, что функциональность ora2pgpro охватывает возможности лишь СУБД Oracle версии не выше 11.2, поскольку именно под данную версию реализовано большинство приложений под Oracle в России. Про возможности более новых версий утилита не знает, однако это не мешает ей работать в том числе и с Oracle 23.

Обработка сложных спецификаций пакетов

Одной из ключевых особенностей ora2pgpro является способность анализировать синтаксис и семантику PL/SQL кода, что позволяет корректно транслировать даже очень сложные и разнообразные объявления в спецификациях пакетов. В отличие от примитивных регулярных выражений, используемых ora2pg, наш подход, основанный на построении абстрактного синтаксического дерева (AST), обеспечивает высокую точность конвертации.

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

Утилита ora2pgpro способна интерпретировать временные типы данных с различной точностью, часовыми поясами и интервалами:

-- PL/SQL
 
    my_date1 DATE := TO_DATE('2023-08-31', 'YYYY-MM-DD');
 
    my_date2 DATE := my_date + 34;

 
    my_timestamp1 TIMESTAMP(1);
 
    my_timestamp2 TIMESTAMP WITH TIME ZONE;
 
    my_timestamp3 TIMESTAMP WITH LOCAL TIME ZONE;
 
    my_timestamp4 TIMESTAMP(9) WITH TIME ZONE;

    my_interval1 INTERVAL DAY TO SECOND(4);
 
    my_interval2 INTERVAL DAY(3) TO SECOND(2);
-- PL/pgSQL
 
    my_date1 timestamp := TO_DATE('2023-08-31', 'YYYY-MM-DD');
 
    my_date2 timestamp := DATETIME_PKG.my_date + 34;
 
 
    my_timestamp1 timestamp;
 
    my_timestamp2 timestamp with time zone;
 
    my_timestamp3 timestamp with time zone;
 
    my_timestamp4 timestamp with time zone;

 
    my_interval1 interval DAY TO SECOND;
 
    my_interval2 interval DAY/*(3)*/ TO SECOND;

Также наша утилита может конвертировать сложные булевы выражения:

-- PL/SQL
 
varchar_var VARCHAR2(100) := 'test';
 
char_var CHAR(10) := 'char2';
 
bool_var1 BOOLEAN := varchar_var LIKE 'ssdsd' || char_var;
 
bool_var2 BOOLEAN;
 
bool_var3 BOOLEAN := TRUE;
 
var1 SYS.ODCINUMBERLIST := SYS.ODCINUMBERLIST(1,2,3,4,5,6,7,8);
 
bool_var3 BOOLEAN := bool_var2 AND TRUE OR
 
    (UPDATING('ID_TABLE') AND NOT var1.EXISTS(3)) OR
 
    var1.EXISTS(8);
-- PL/pgSQL
 
varchar_var varchar(100) := 'test';
 
char_var char(10) := 'char2';
 
bool_var1 BOOLEAN := BOOL_PKG.varchar_var LIKE 'ssdsd' || BOOL_PKG.char_var;
 
bool_var2 BOOLEAN;
 
bool_var3 BOOLEAN := TRUE;
 
var1 SYS.ODCINUMBERLIST := SYS.ODCINUMBERLIST(1,2,3,4,5,6,7,8);
 
bool_var3 BOOLEAN := BOOL_PKG.bool_var2 AND TRUE OR
 
    (UPDATING('ID_TABLE') AND NOT var1.EXISTS(3)) OR
 
    var1.EXISTS(8);

Помимо временных типов и сложных булевых выражений, ora2pgpro способна корректно распознавать и транслировать пользовательские типы данных VARRAY и RECORD, сложные инициализации переменных, объявления констант и другие конструкции.

Утилита ora2pgpro способна корректно распознавать и транслировать все эти конструкции, обеспечивая точное соответствие типов данных Oracle типам данных Postgres Pro Enterprise, а также преобразуя сложные выражения и вызовы методов в эквивалентные конструкции PL/pgSQL. Это значительно снижает объём ручной доработки после автоматической миграции.

Выводы

Опыт миграции с Oracle на Postgres Pro Enterprise показывает, насколько важна автоматизация и адаптация инструментов под особенности целевой СУБД. ora2pgpro успешно решает задачи экспорта сложных объектов, обеспечивая поддержку функциональности, которой в «ванильной» PostgreSQL попросту нет. Результатом является улучшение производительности и надёжности процесса миграции, что открывает новые перспективы в развитии инфраструктуры баз данных и снижении операционных рисков.

Теги:
Хабы:
+6
Комментарии2

Публикации

Информация

Сайт
www.postgrespro.ru
Дата регистрации
Дата основания
Численность
501–1 000 человек
Местоположение
Россия
Представитель
Иван Панченко