01 Data Transform · Продукты · Коннектор

O2PG Connector — прокси-транслятор протокола Oracle

Приложение подключается так, будто перед ним Oracle: тот же протокол, тот же порт, тот же драйвер. За прокси уже PostgreSQL.

О продукте

Прокси-транслятор запросов O2PG предназначен для облегчения миграции баз данных с Oracle на PostgreSQL. Он обеспечивает совместимость на уровне SQL-запросов, позволяя приложениям, изначально разработанным для Oracle, работать с PostgreSQL без изменений в коде конечного приложения.

Переход с Oracle на PostgreSQL сложен из-за различий в SQL-диалектах и функциональных возможностях: диалект запросов, типы данных, встроенные функции, поведение драйвера на уровне протокола. O2PG берёт эти различия на себя.

Схема работы O2PG

Из чего состоит продукт

  • Прокси-сервер перехватывает SQL-запросы приложений и преобразует их в совместимый с PostgreSQL формат.
  • Мигратор базы данных переносит схемы и данные из Oracle в PostgreSQL.

Что требуется от вас

Настроить приложения на подключение к прокси-серверу O2PG вместо Oracle и разово выполнить миграцию данных мигратором. Остальное берёт на себя прокси: приложение продолжает работать так же, как работало с Oracle.

Установка

Типовой пример конфигурации и шаги для развёртывания O2PG Proxy через Docker Compose.

1. docker-compose.yml

services:
  proxy:
    image: cr.yandex/crpgr3sfcpa3lqqkvupn/o2pg-proxy:latest
    ports:
      - "1521:1521"
    environment:
      POSTGRES_HOST: localhost
      POSTGRES_PORT: 5432
      POSTGRES_DB: postgres
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: password
    env_file:
      - config.env
            

2. Запуск

docker compose up -d
            

3. Параметры подключения к PostgreSQL

Переменная По умолчанию Назначение
POSTGRES_HOST localhost IP или хост PostgreSQL
POSTGRES_PORT 5432 порт PostgreSQL
POSTGRES_DB postgres имя базы данных
POSTGRES_USER postgres имя пользователя
POSTGRES_PASSWORD пароль пользователя

4. Лицензионный ключ

Рядом с docker-compose.yml создайте файл config.env:

LICENSE=<ваш_лицензионный_ключ>
            

5. Проверка

После запуска прокси доступен на порту 1521 хоста — том же, который привычен Oracle-клиентам. Переключите приложение на этот адрес и выполните любой запрос: он уйдёт в PostgreSQL уже транслированным.

6. Рекомендации для промышленной среды

  • Если PostgreSQL запущен в отдельном контейнере или на другом хосте, укажите соответствующий POSTGRES_HOST и порт и настройте сеть Docker.
  • Секреты храните в Docker secrets или внешнем менеджере секретов, а не открытым текстом в файлах.
  • Если порт 1521 занят, измените маппинг в секции ports на свободный порт хоста.

Поддержка типов данных

Перечень типовых Oracle-типов и их соответствий. Поддерживаются не все типы, но реализованная часть покрывает большинство сценариев реальных приложений. Список расширяется с каждой версией; строки с бирюзовой гранью — поддерживаемые.

Код Тип данных Описание
1 VARCHAR2(size) Строка символов переменной длины, максимальная длина указывается в size.
1 NVARCHAR2(size) Строка Unicode переменной длины, содержащая до size символов.
2 NUMBER(p, s) * Число с точностью p и масштабом s. Точность p от 1 до 38; масштаб s от -84 до 127. Для хранения требуется от 1 до 22 байт.
8 LONG Символьные данные переменной длины до 2 ГБ (предназначено для обратной совместимости).
12 DATE Диапазон: с 01.01.4712 до 31.12.9999. Формат определяется NLS_DATE_FORMAT или NLS_TERRITORY. Размер фиксирован — 7 байт; содержит год, месяц, день, час, минуту и секунду.
100 BINARY_FLOAT 32‑битное число с плавающей запятой (4 байта).
101 BINARY_DOUBLE 64‑битное число с плавающей запятой (8 байт).
180 TIMESTAMP[(fractional_seconds_precision)] Значение даты и времени с опцией дробной части секунд (fractional_seconds_precision от 0 до 9, по умолчанию 6).
181 TIMESTAMP[(fractional_seconds_precision)] WITH TIME ZONE Как TIMESTAMP, плюс смещение часового пояса.
231 TIMESTAMP[(fractional_seconds_precision)] WITH LOCAL TIME ZONE Как TIMESTAMP WITH TIME ZONE, но при хранении нормализуется по часовому поясу базы; при извлечении показывается в часовом поясе сеанса.
182 INTERVAL YEAR[(year_precision)] TO MONTH Период в годах и месяцах. year_precision от 0 до 9 (по умолчанию 2). Размер — 5 байт.
183 INTERVAL DAY[(day_precision)] TO SECOND[(fractional_seconds_precision)] Период в днях, часах, минутах и секундах. day_precision от 0 до 9 (по умолчанию 2). fractional_seconds_precision от 0 до 9 (по умолчанию 6).
23 RAW(size) Необработанные двоичные данные длиной size байт. Максимум: 32767 байт при MAX_STRING_SIZE = EXTENDED, 2000 байт при STANDARD.
24 LONG RAW Необработанные двоичные данные переменной длины до 2 ГБ.
69 ROWID Адрес строки в таблице в Base64 — используется для значений псевдостолбца ROWID.
208 UROWID[(size)] Логический адрес строки таблицы, организованной по индексу. Необязательный size (по умолчанию максимум — 4000 байт).
96 CHAR[(size [BYTE/CHAR])] Символьные данные фиксированной длины (size). Максимум 2000 байт. BYTE/CHAR определяют семантику, аналогичную VARCHAR2.
96 NCHAR[(size)] Символьные данные фиксированной длины size (национальный набор символов). Максимум зависит от кодировки (AL16UTF16 до 2×size байт, UTF8 до 3×size байт), верхний предел — 2000 байт.
112 CLOB Большой символьный объект (однобайтовые или многобайтовые символы). Максимум: (4 ГБ - 1) * размер блока БД.
112 NCLOB Большой символьный объект Unicode. Максимум: (4 ГБ - 1) * размер блока БД.
113 BLOB Большой двоичный объект. Максимум: (4 ГБ - 1) * размер блока БД.
102 REF CURSOR Тип переменной, содержащий ссылку на курсор; используется для передачи наборов данных из хранимых процедур.

* Точность может находиться в пределах от 1 до 18.

Специальные типы данных (например, osg, xml и т.д.) не поддерживаются.

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

Встроенные функции Oracle по категориям. Таблица длинная — пользуйтесь поиском над ней, чтобы найти конкретную функцию.

Числовые функции

Функция Описание
ABS(n) Возвращает абсолютное значение числа n.
ACOS(n) Возвращает арккосинус числа n.
ASIN(n) Возвращает арксинус числа n.
ATAN(n) Возвращает арктангенс числа n.
ATAN2(n,m) Возвращает арктангенс чисел n и m.
BITAND(n,m) Возвращает результат битовой операции and чисел n и m.
CEIL(n) Возвращает наименьшее целое число, большее или равное n.
COS(n) Возвращает косинус числа n.
COSH(n) Возвращает гиперболический косинус числа n.
EXP(n) Возвращает e возведенное в n степень, где e= 2,71828183 ...
FLOOR(n) Возвращает наибольшее целое число, равное или меньшее n.
LN(n) Возвращает натуральный логарифм числа n.
LOG(m,n) Возвращает логарифм числа n по основанию m.
MOD(m,n) Возвращает остаток от m деления на n.
NANVL(m,n) Вернуть альтернативное значение,n если входное значение m равно NaN
POWER Возвращает m возведённое в степень n.
REMAINDER Возвращает остаток от m деления на n.
ROUND(n,i) Возвращает n округлённое число до i знаков справа от десятичной точки. Если не указано integer, n округляется до 0 знаков. Аргумент integer может быть отрицательным для округления знаков слева от десятичной точки.
SIGN(n) Возвращает знак n.
SIN(n) Возвращает синус числа n.
SINH(n) Возвращает гиперболический синус числа n.
SQRT(n) Возвращает квадратный корень из n.
TAN(n) Возвращает тангенс числа n.
TANH(n) Возвращает гиперболический тангенс числа n.
TRUNC(n,m) Возвращает n число, усеченное до m десятичных знаков. Если m опущено, число n усекается до 0 знаков. m может быть отрицательным, чтобы обнулить m цифры слева от десятичной точки.
WIDTH_BUCKET(exp,min,max,buckets) Позволяет строить гистограммы равной ширины, в которых диапазон гистограммы делится на интервалы одинакового размера.

Символьные функции, возвращающие символьные значения

Функция Описание
CHR(n using nchar_cs) * возвращает символ, имеющий двоичный эквивалент в n качестве VARCHAR2 значения либо в наборе символов базы данных, либо, если указано USING NCHAR_CS, в национальном наборе символов.
CONCAT(char1,char2) возвращает результат char1 конкатенации с char2
INITCAP(char) Возвр ащает char, где первая буква каждого слова заглавная, все остальные буквы — строчные.
LOWER(char) Возвращает char, со всеми строчными буквами.
LPAD(expr1,n,expr2) Возвращает expr1, дополненный слева до длины n символов, с последовательностью символов в expr2.
LTRIM(char,set) Удаляет с левого конца char все символы, содержащиеся в set. Если не указано set, по умолчанию используется один пробел.
NLS_INITCAP(char,'nlsparam') Возвращает char, где первая буква каждого слова заглавная, все остальные буквы — строчные. Значение 'nlsparam' может иметь следующую форму: 'NLS_SORT = сортировка', где sort — либо лингвистическая последовательность сортировки, либо BINARY.
NLS_LOWER(char,'nlsparam') Аналогично LOWER. Может 'nlsparam' иметь ту же форму и служить той же цели, что и в NLS_INITCAP функции.
NLSSORT(char,'nlsparam') Возвращает строку байтов, использованную для сортировки char. 'NLS_SORT = сортировка', где sort — лингвистическая последовательность сортировки или BINARY.
NLS_UPPER Аналогично UPPER. Может 'nlsparam' иметь ту же форму и служить той же цели, что и в NLS_INITCAP функции.
REGEXP_REPLACE(char,regexp,...) Расширяет функциональность функции REPLACE, позволяя искать строку по шаблону регулярного выражения.
REGEXP_SUBSTR Расширяет функциональность функции SUBSTR, позволяя выполнять поиск в строке по шаблону регулярного выражения.
REPLACE(char,search_string,replacement_string) ** Возвращает char, при этом каждое вхождение search_string заменяется на replacement_string. Если replacement_string опущено или равно NULL, то все вхождения search_string удаляются. Если search_string равно NULL, то char возвращается.
RPAD(exp1,i,exp2) Возвращает expr1, дополненный справа до заданной длины n символами expr2, повторяется i раз.
RTRIM(char,set) Удаляет с правого конца char все символы, встречающиеся в set.
SOUNDEX(char) Возвращает строку символов, содержащую фонетическое представление char.
SUBSTR(string,position,substring_length) Возвращают часть string, начиная с символа position, substring_length длиной символов.
TRANSLATE(exp,from_string,to_string) Возвращает результат expr, в котором все вхождения каждого символа в from_string заменяются соответствующими символами в to_string.
TREAT(exp as ref) Заменяет объявленный тип выражения.
TRIM(exp,set) *** Позволяет обрезать начальные или конечные символы exp (или и те, и другие) из set. Если указать LEADING, то Oracle Database удалит все начальные символы, равные trim_character. Если указать TRAILING, то Oracle удалит все конечные символы, равные trim_character.
UPPER(char) Возвращает char, со всеми заглавными буквами.

* Выражение USING NCHAR_CS не поддерживается.

** replacement_string должно присутствовать. Если replacement_string=NULL - результат NULL.

*** Не поддерживает ключевые слова LEADING TRAILING.

Символьные функции, возвращающие числовые значения

Функция Описание
ASCII( char) Возвращает десятичное представление в наборе символов базы данных первого символа char.
INSTR(char,set,pos,i) Возвращает целое число, указывающее позицию символа, который является первым символом вхождения из set. Поиск производится с позиции pos, ищется i-е вхождение.
LENGTH(char) Возвращают длину char в символах.
REGEXP_INSTR Расширяет функциональность функции INSTR, позволяя выполнять поиск в строке по шаблону регулярного выражения.

Функции даты и времени

Функция Описание
ADD_MONTHS(date,integer) Возвращает дату date плюс integer месяцы
CURRENT_DATE Возвращает текущую дату в часовом поясе сеанса в значении григорианского календаря типа данных DATE
CURRENT_TIMESTAMP Возвращает текущую дату и время в часовом поясе сеанса в виде значения типа datatype TIMESTAMP WITH TIME ZONE
DBTIMEZONE Возвращает значение часового пояса базы данных.
EXTRACT (datetime) Извлекает и возвращает значение указанного поля datetime из выражения, содержащего значение datetime или интервал.
FROM_TZ(timestamp_value,timezone_value) Преобразует значение временной метки и часовой пояс в TIMESTAMP WITH TIME ZONE значение. time_zone_value — это строка символов в формате 'TZH:TZM' или символьное выражение, которое возвращает строку в TZR необязательном TZD формате
LAST_DAY(date) Возвращает дату последнего дня месяца, содержащего date
LOCALTIMESTAMP Возвращает текущую дату и время в часовом поясе сеанса в виде значения типа datatype TIMESTAMP.
MONTHS_BETWEEN(date1,date2) Возвращает количество месяцев между датами date1 и date2.
NEW_TIME(date,timezone1,timezone2) Возвращает дату и время в часовом поясе, timezone2 если дата и время в часовом поясе timezone1 равны date.
NEXT_DAY(date,char) Возвращает дату первого дня недели, указанного параметром , char который наступает позже, чем дата date.
NUMTODSINTERVAL(n,interval_unit) Преобразует n в INTERVAL DAY TO SECOND литерал. Значения для interval_unit 'DAY','HOUR','MINUTE','SECOND'
NUMTOYMINTERVAL(n,interval_unit) Преобразует число n в INTERVAL YEAR TO MONTH литерал. Значения для interval_unit ' YEAR',' MONTH'
ROUND (date,fmt) Возвращает date округлённое до единицы, заданной моделью формата fmt.
SESSIONTIMEZONE Возвращает часовой пояс текущего сеанса
SYS_EXTRACT_UTC(datetime_with_time_zone) Извлекает UTC (всемирное координированное время — ранее среднее время по Гринвичу) из значения datetime со смещением часового пояса или названием региона часового пояса
SYSDATE Возвращает текущую дату и время, установленные для операционной системы, в которой находится база данных
SYSTIMESTAMP Возвращает системную дату, включая доли секунды и часовой пояс, системы, в которой находится база данных.
TO_CHAR (datetime,fmt,nlsparam) * Преобразует значение datetime или интервала типа DATE, TIMESTAMP, TIMESTAMP WITH TIME ZONE, или TIMESTAMP WITH LOCAL TIME ZONE в значение типа VARCHAR2 в формате, заданном параметром date format fmt
TO_TIMESTAMP(char,fmt,nlsparam) * Преобразует char, CHAR, VARCHAR2, NCHAR или NVARCHAR2 в значение TIMESTAMP.
TO_TIMESTAMP_TZ(char,fmt,nlsparam) Преобразует char, CHAR, VARCHAR2, NCHAR или NVARCHAR2 в значение TIMESTAMP WITH TIME ZONE.
TO_DSINTERVAL(char,nlsparam) Преобразует строку символов типа CHAR, VARCHAR2, NCHAR, или NVARCHAR2 в INTERVAL DAY TO SECOND
TO_YMINTERVAL(char,nlsparam) Преобразует строку символов типа CHAR, VARCHAR2, NCHAR, или NVARCHAR2в в INTERVAL YEAR TO MONTH, где char— преобразуемая строка символов.
TRUNC(date,fmt) Возвращает date - значение, представляющее собой часть времени суток, усеченную до единиц, указанных в модели формата fmt.
TZ_OFFSET(time_zone_name,arg) Возвращает смещение часового пояса, соответствующее аргументу, на основе даты выполнения оператора.

* Возможны отличия в формате даты.времени (см Модели форматов). Параметр nlsparam не поддерживается.

Поддержка TTC-функций

TTC (Two-Task Common) — уровень протокола, на котором драйвер Oracle общается с сервером. Прокси реализует этот слой сам: он отвечает клиенту так, как ответил бы Oracle, поэтому драйвер не замечает подмены.

Что реализовано на этом уровне

  • согласование версии протокола и параметров сессии при подключении;
  • описание курсоров и метаданных результата;
  • выборка строк порциями, включая повторные обращения за продолжением;
  • операции с LOB — чтение и запись больших объектов;
  • piggyback-запросы, которые драйвер прикладывает к основным вызовам.

Проверенные драйверы

Линейка Версия
ojdbc8 19c 19.32.0.0 *
ojdbc8 23ai 23.2.0.0
ojdbc11 23ai 23.26.3.0.0
ojdbc17 23ai 23.26.3.0.0

* На ojdbc8 19.x не поддерживается работа с временными LOB через LOB API (Connection.createClob(), запись BLOB потоком без указания длины). Обходится обычными setString / setBytes. На линейке 23ai этот путь работает.

Линейка 23ai проверяется по краям диапазона — на 23.2 и 23.26, поэтому промежуточные релизы 23.x также считаются поддерживаемыми. Драйверы старше 19c не проверяются и не поддерживаются.

Второй продукт семейства O2PG Migrator — перенос схем и данных из Oracle в PostgreSQL