PostgreSQL вместо Oracle: что переезжает легко, а где надо готовиться
Клиент попросил оценить миграцию с Oracle SE на PostgreSQL. Разбираем gap-анализ: SQL и индексы идут почти без изменений, а PL/SQL-пакеты и sequences требуют доработки.
Рост санкционных рисков подталкивает бизнес рассматривать PostgreSQL как замену Oracle и MSSQL
В феврале к нам обратился клиент с конкретным запросом: «хотим понять, насколько реально уйти с Oracle SE на PostgreSQL и что это потребует». Не «перейдите нас», а именно оценка - что вообще предстоит. Санкционная тема звучит у бизнеса всё громче, Oracle стоит ощутимо, и вопрос из разряда «когда-нибудь подумаем» довольно быстро перешёл в «нужна конкретная оценка».
Мы провели gap-анализ по их схеме. Делимся тем, что увидели - без обещаний что будет просто, но и без запугивания.
Что переезжает практически без боли
Стандартный SQL. SELECT, JOIN, GROUP BY, оконные функции, CTE - всё это в PostgreSQL есть и синтаксически очень близко к Oracle. Большинство читабельных запросов к витринам перешло бы с минимальными правками. Типы данных - отдельная история, но базовые (числа, строки, даты, CLOB-аналоги через text) покрываются.
Индексы. B-tree, составные индексы, частичные индексы - в PostgreSQL это работает и по семантике совпадает с Oracle. Bitmap-индексы в явном виде нет, но планировщик PostgreSQL умеет строить bitmap scan на лету из обычных B-tree, и для большинства аналитических запросов результат сопоставимый. Функциональные индексы - тоже есть.
Репликация. Oracle SE ограничен в возможностях репликации без дорогих опций. PostgreSQL streaming replication + hot standby - это штатный механизм, работающий без доплат. Реплику для чтения и failover-стенд организовать проще, чем в Oracle SE. Мы уже работаем с этим на тестовых стендах.
Базовое администрирование. Резервное копирование через pg_dump / pg_basebackup, мониторинг через системные представления, управление правами - всё привычно любому DBA, кто читал документацию хотя бы по одной реляционной СУБД.
Где надо готовиться
Sequences. В Oracle sequences - отдельные объекты с NEXTVAL/CURRVAL, к которым обращаются через двоеточие в SQL. В PostgreSQL sequences тоже есть, синтаксис другой: nextval('seq_name'). Автоинкрементные столбцы через SERIAL или BIGSERIAL работают по-своему - под капотом тоже sequence, но заводится автоматически и в явном коде не видна. При миграции надо пройтись по всем местам где sequence используется явно - их может быть много, особенно в процедурном коде.
PL/SQL-пакеты. Вот здесь главная работа. Oracle PL/SQL - это полноценный язык с пакетами, типами, исключениями, автономными транзакциями и курсорами со своей семантикой. PostgreSQL предлагает PL/pgSQL - близко, но не одно и то же. Пакетов как объекта нет вообще: логику пакетов надо раскладывать по схемам и обычным функциям. Конструкции %TYPE, %ROWTYPE, RECORD-типы есть аналоги, но с нюансами. Автономные транзакции через PRAGMA AUTONOMOUS_TRANSACTION - в PostgreSQL это делается через dblink, что заметно сложнее.
У клиента оказалось несколько десятков пакетов - ETL-логика, триггеры аудита, процедуры расчётов. Часть из них не очень объёмная, но со специфическими Oracle-конструкциями. Это ручная работа: автоматические конверторы дают скелет, но каждую процедуру надо проверять.
CONNECT BY и иерархические запросы. Oracle-специфика, которая у клиента встречается. В PostgreSQL это закрывается рекурсивными CTE (WITH RECURSIVE), но синтаксис кардинально другой - просто заменой не обойтись, надо переписывать логику.
Hints оптимизатора. В Oracle принято явно управлять планом через hints (/*+ INDEX(...) */, /*+ USE_NL(...) */). PostgreSQL hints не поддерживает как встроенную конструкцию - есть расширение pg_hint_plan, но это отдельная история. Запросы, которые в Oracle «едут» только потому что там прибит конкретный план - придётся разбирать и добиваться нужного поведения другими способами: через статистику, параметры планировщика, переписыванием запроса.
Схема именования и связанные объекты. Oracle использует понятие схемы = пользователя, в PostgreSQL схемы отдельные. При миграции таблицы и объекты надо раскладывать по схемам PostgreSQL вручную, соответственно пересматривается весь код с квалифицированными именами.
Как это выглядит на практике
Мы разложили объекты схемы по категориям:
- Таблицы и представления - большинство переедут с минимальными правками по типам данных.
- Простые хранимые процедуры и функции - переписать реально, трудоёмкость умеренная.
- PL/SQL-пакеты со сложной логикой - основной объём ручной работы, здесь не угадать без детального разбора каждого пакета.
- Специфические Oracle-конструкции (CONNECT BY, MERGE с расширенным синтаксисом, hints) - каждый случай разбирается отдельно.
Идея «запустить конвертор и потом потестировать» не работает для нетривиальной схемы. Конвертор сэкономит время на DDL и на простых DML, но процедурный код требует человека с пониманием обеих платформ.
Где мы сейчас
Gap-анализ сделан, клиент получил оценку трудоёмкости по каждому блоку. Решение о старте миграции ещё не принято - это нормально, там есть и бюджетный вопрос, и вопрос рисков для работающего продуктива. Пока планируем подготовить тестовый стенд на PostgreSQL и прогнать несколько ключевых пакетов вручную - чтобы оценка трудоёмкости была не теоретической, а с реальными примерами.
Всё что касается хранилищ данных и миграции аналитических баз - в рамках DWH и аналитики.