О продукте
Прокси-транслятор запросов O2PG предназначен для облегчения миграции баз данных с Oracle на PostgreSQL. Он обеспечивает совместимость на уровне SQL-запросов, позволяя приложениям, изначально разработанным для Oracle, работать с PostgreSQL без изменений в коде конечного приложения.
Переход с Oracle на PostgreSQL сложен из-за различий в SQL-диалектах и функциональных возможностях: диалект запросов, типы данных, встроенные функции, поведение драйвера на уровне протокола. 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 не проверяются и не поддерживаются.