Оценка трудоемкости миграции Oracle в PostgreSQL до старта
Оценка трудоемкости миграции Oracle в PostgreSQL: простая методика инвентаризации объектов, балльная оценка пакетов, триггеров и джобов, чтобы заранее увидеть объем работ.

Зачем оценивать трудоемкость до старта
Перенос данных обычно делается быстрее, чем перенос логики. Таблицы можно выгрузить и загрузить, а затем проверить сверками и контрольными суммами. Бизнес-правила в Oracle чаще разбросаны по пакетам, триггерам, джобам, пользовательским типам и мелким «удобным» возможностям, к которым привыкли годами. Именно это чаще всего и съедает сроки.
Если стартовать без первичной оценки, сюрпризы почти неизбежны. Пакет, который выглядит как «пара процедур», может тянуть десятки зависимостей, глобальные переменные и нетривиальные исключения. Триггеры незаметно правят данные, запрещают операции, ведут аудит. Джобы и расписания завязаны на инфраструктуру и привилегии. А специфичные типы и особенности Oracle (например, коллекции, нюансы дат и строк) иногда требуют переработки схемы и кода.
До того как называть сроки и собирать команду, полезно ответить на три вопроса: сколько логики реально придется переписать, что перенесется почти напрямую, и где риски максимальны. Тогда оценка становится не «угадайкой», а управляемым планированием.
Хорошая первичная оценка дает конкретные артефакты: реестр ключевых объектов и их зависимостей, грубую классификацию сложности, список зон риска (что может ударить по учету, платежам, отчетности, аудиту), понимание нужных ролей в команде и черновой порядок работ.
Простой пример: в модуле «начисления» данные переносятся за день, но расчет держится на 15 триггерах и одном большом пакете с общей памятью. Без оценки это вскроется уже в разработке, когда сроки и бюджет будет сложно пересобрать.
Что именно оцениваем и где ставим границы
Первичная оценка начинается не с подсчета объектов, а с рамок. Если их не зафиксировать, любая «красивая цифра» развалится на первой же неделе, когда всплывут неучтенные схемы, джобы или интеграции.
Определите периметр: какие схемы и модули входят в работу, какие среды учитываются (dev, test, prod), и что происходит вокруг базы. Если часть логики живет в БД, а часть в приложении, без согласованных границ оценка будет постоянно «расти» из-за споров, что именно переносится.
Договоритесь, что именно вы называете миграцией. На практике это обычно один из уровней:
- структура и данные (DDL + данные);
- вся серверная логика (пакеты, процедуры, функции, триггеры);
- плюс эксплуатация (расписания, мониторинг, бэкапы, права, роли);
- плюс изменения в приложении (драйвер, SQL-диалект, транзакции, обработка ошибок).
Дальше соберите минимум артефактов, без которых оценка почти всегда занижена: DDL схем, исходники PL/SQL (включая пакеты), определения триггеров, конфиги планировщика (DBMS_SCHEDULER/DBMS_JOB), права и роли, список внешних зависимостей (очереди, внешние таблицы, dblink, файловые операции).
И отдельно зафиксируйте допущения: версию Oracle (и используемые режимы), целевую версию PostgreSQL, требования к совместимости поведения и критерии «готово». Полезно сразу записать, что не входит в оценку, если это не согласовано: редизайн модели данных, оптимизация запросов, рефакторинг бизнес-логики.
Когда границы ясны, инвентаризация становится сравнимой между модулями, а обсуждение сроков - предметным.
Инвентаризация объектов: минимальный набор, чтобы не промахнуться
Оценка чаще всего ломается об одно: считают «схему», а на деле мигрируют правила, автоматизацию и доступ. Поэтому инвентаризация должна быть короткой, но покрывать все классы объектов.
По каждому объекту зафиксируйте минимум: имя, владелец (схема), назначение в одной фразе, объем кода (если это код), и главное - есть ли зависимость от Oracle-специфики. Этого достаточно, чтобы разнести объекты по категориям «легко/средне/тяжело».
В реестр обычно стоит включить:
- данные и структуру: таблицы, секционирование, индексы, представления (включая materialized), последовательности;
- код и бизнес-логику: процедуры, функции, пакеты (спеки и тела), триггеры;
- планировщик и интеграции: DBMS_SCHEDULER/DBMS_JOB, внешние вызовы (shell, HTTP, очереди), зависимости от файлов;
- безопасность и «склейки»: синонимы, роли, привилегии, политики доступа, аудит;
- хранилища и файлы: LOB (BLOB/CLOB), внешние таблицы, операции с директориями.
Дальше не нужно сразу уходить в детали. Важно увидеть, где спрятана логика. Модуль «Счета» может выглядеть простым: 20 таблиц и 30 индексов. Но в реестре всплывает пакет на 8 000 строк, триггеры, которые пересчитывают лимиты, и джобы, закрывающие период ночью. Вот это и определяет реальный объем.
Практичное правило: если объект влияет на данные без участия приложения (триггеры, джобы, пакетные процедуры), он должен быть в списке всегда, даже если кажется «вспомогательным».
Пакеты и PL/SQL: как быстро прикинуть объем переписывания
Пакеты в Oracle часто держат основную бизнес-логику, поэтому они сильнее всего влияют на сроки. Для первичной прикидки не нужно вчитываться в каждую строку. Важно понять размер и форму работы: сколько единиц логики, насколько они связаны и какие места не перенесутся напрямую.
Начните с грубого счета: сколько пакетов, сколько процедур и функций внутри, и какой объем кода (условно: маленький до 300-500 строк, средний до 2000, большой выше). Обязательно смотрите и спецификацию, и тело: интерфейс может быть небольшим, а реализация - перегруженной ветвлениями и побочными эффектами.
Чаще всего сроки «раздувают» обработка исключений с тонкой бизнес-логикой, курсоры (особенно с состоянием и несколькими проходами) и динамический SQL, где запрос собирается из строк и зависит от параметров. Это нередко требует не перевода, а перепроектирования.
Отметьте зависимости пакета от таблиц, представлений, триггеров и джобов. Если пакет вызывает другие пакеты или использует общие типы и константы, переписывание превращается в «цепочку».
Признаки высокой сложности, которые стоит пометить сразу: глубокая вложенность CASE/IF, много режимов работы и параметров, активный динамический SQL, COMMIT/ROLLBACK внутри, сильная завязка на Oracle-специфику.
Триггеры: где прячутся скрытые правила
Триггеры часто выглядят как «мелкие правила у таблицы», но на практике в них прячется бизнес-логика, аудит и побочные эффекты. Если их не учесть на старте, оценка почти всегда получится заниженной.
Сначала определите масштаб: сколько триггеров и на каких таблицах, какие события покрывают (INSERT, UPDATE, DELETE). На одной ключевой таблице может висеть 5-10 триггеров, и вместе они формируют поведение модуля.
Быстро разделите триггеры по назначению
Полезно отделить контроль данных от интеграций. Контроль часто можно приблизить к модели: ограничения, значения по умолчанию, вычисляемые поля, проверки целостности. Интеграции обычно требуют переписывания вокруг приложения или отдельного сервиса.
На практике триггеры чаще всего относятся к одному из типов: валидация и запреты, автозаполнение, каскадные изменения, логирование и аудит, интеграции (очереди, внешние вызовы, уведомления).
Побочные эффекты и признаки высокой сложности
Опасность триггеров в неочевидных последствиях: одно обновление приводит к серии дополнительных записей или обновлений. Для оценки отметьте «красные флаги»: обращения к множеству таблиц, циклы по строкам, сложная обработка статусов, зависимость от времени, записи в лог или очередь.
Отдельно проверьте триггеры, которые логичнее заменить не триггером. Например, дату создания почти всегда проще задать через DEFAULT, а часть проверок перенести в CHECK или внешние ключи. Это уменьшает объем переписывания и упрощает тестирование.
Минимальный технический шаг для инвентаризации можно сделать одним запросом в Oracle:
SELECT table_name, trigger_name, triggering_event, status
FROM user_triggers
ORDER BY table_name, trigger_name;
Дальше для каждого триггера достаточно короткой карточки: таблица, событие, что меняет, какие таблицы трогает, есть ли внешние эффекты.
Джобы и расписания: оценка переносимости и рисков
С джобами часто «вылезает» реальная сложность: это не только SQL. За расписанием может стоять цепочка вызовов процедур, обновления витрин, генерация отчетов, выгрузки в файлы и запуск внешних скриптов. Поэтому важно понимать не «сколько джобов», а «что они делают» и где у них границы.
Критичность расписаний определяется ценой ошибки. Отметьте процессы с ночным окном, почасовые расчеты и задания почти реального времени. Чем меньше допустимое окно, тем выше требования к мониторингу, очередям и повторным запускам.
Быстрый фильтр переносимости
По каждой задаче полезно собрать 4-5 признаков: что запускается (SQL, процедура, пакет, внешний скрипт), где зависимости (файлы, SFTP, почта, API), какие права нужны (директории, учетные записи, ключи), есть ли состояние (промежуточные таблицы, очереди, контрольные точки), как устроен перезапуск.
Риски простоя и восстановление после сбоя
Проверьте, что будет, если джоб упал на середине. В Oracle это могли «прикрывать» транзакциями и флажками статуса. В PostgreSQL логику часто нужно сделать явной: идемпотентность (повторный запуск без дублей), журналирование шагов, безопасная очистка временных данных. Если этого нет, оценка должна включать не только перенос расписания, но и доработку сценариев восстановления.
Специфические типы и возможности Oracle: быстрый фильтр сложности
Сроки чаще всего «взрываются» не на таблицах и простых запросах, а на местах, где Oracle дает особые типы и сервисные пакеты. Быстрый фильтр помогает заранее увидеть, где миграция будет прямой, а где потребуется переработка.
Сначала отметьте объекты, которые почти всегда требуют отдельного решения: XMLTYPE, пользовательские типы (UDT), VARRAY и nested tables. В PostgreSQL многое можно заменить, но цена замены разная: иногда достаточно jsonb и обычных таблиц, а иногда придется менять контракт данных и код.
Параллельно проверьте «пакеты-расширения» Oracle. DBMS_SCHEDULER, UTL_FILE, UTL_HTTP и похожие вещи завязаны на окружение, права, файловую систему и сетевые правила. В PostgreSQL это чаще уходит во внешние сервисы, фоновые задания, расширения или в код приложения.
Отдельно пометьте инфраструктурные фичи, которые влияют на поведение и производительность: секционирование, материализованные представления, специфичные индексы (например, bitmap), компрессия, hints.
Короткий фильтр сложности:
- есть ли прямой аналог в PostgreSQL или расширении;
- используется ли функция в критичном бизнес-потоке;
- зависит ли она от ОС, файлов или сети;
- нужна ли прежняя производительность «как в Oracle»;
- можно ли поменять подход без потери требований.
По каждому пункту фиксируйте решение: «аналог есть», «нужна переработка» или «меняем подход». Например, XMLTYPE в отчетном модуле часто уходит в jsonb и преобразование на входе, а UTL_FILE почти всегда требует пересмотра: куда писать файлы, кто имеет доступ и как это мониторить.
Балльная методика: как перевести инвентарь в оценку трудозатрат
Чтобы первичная оценка не превратилась в гадание, удобно перевести инвентарь объектов в баллы. Идея простая: каждому объекту даете базовые баллы сложности, умножаете на вес типа объекта и на коэффициенты риска. На выходе получается не «точная смета», а понятный диапазон и список того, что тянет проект вниз.
1) Сложность: 3 уровня с понятными признаками
Шкала должна быть одинаково понятна всей команде. Например: простое (1), среднее (3), сложное (7).
Критерии можно держать короткими: простое - мало условий и нет динамического SQL; среднее - несколько веток логики, курсоры, обработка ошибок; сложное - динамический SQL, сильная завязка на Oracle-особенности, много исключений, нетривиальная транзакционность или жесткие требования по производительности.
2) Вес по типу объекта и риск-коэффициенты
Базовые баллы умножайте на вес типа объекта, чтобы одинаковая «сложность 3» у триггера и у пакета не выглядела одинаково. Для старта достаточно таких групп:
- пакеты/процедуры/функции: x3;
- триггеры: x2;
- джобы/расписания: x2;
- специфичные фичи Oracle (типы, встроенные пакеты, особенности SQL): x4;
- «простые» объекты (таблицы, индексы без экзотики): x1.
Сверху добавьте коэффициенты риска (обычно 1.1-1.5) и применяйте их только там, где они реально есть: слабая документация, высокая бизнес-критичность, много интеграций/внешних вызовов, жесткие требования по времени ответа.
Практичный результат: суммарные баллы по модулю и «топ-10» объектов по вкладу. По ним и планируйте короткую проверку (spike) перед финальным планом: часто 10% объектов дают 60-80% трудозатрат.
Частые ошибки первичной оценки
Самая дорогая ошибка на старте - считать только количество объектов и по нему выводить сроки. Реальная сложность сидит в связях между объектами и в неявных допущениях, которые годами жили в коде.
Первая ловушка - зависимости. Один пакет может дергать десятки таблиц, представлений, триггеров, синонимов и других пакетов. Если оценить только текст самого пакета, а не его «хвост», сроки почти гарантированно будут занижены. На практике это выглядит так: переносите модуль, а затем «догоняете» отсутствующие функции и типы, потому что они всплывают только при сборке и тестах.
Вторая ошибка - забыть про права, роли и схемы. В Oracle доступ часто держится на ролях, грантах «через роль» и особенностях definer/invoker. В PostgreSQL поведение другое, и проблемы проявляются не при переносе данных, а когда пользователи начинают работать.
Третья - недооценка типов, дат и строк. Разница между пустой строкой и NULL, неявные преобразования, кодировки, NLS-настройки, временные зоны, DATE vs TIMESTAMP дают тихие ошибки: запрос «работает», но результаты чуть другие.
Что стоит проверить на старте:
- фиксируете зависимости: что вызывает пакет/триггер и что вызывает их;
- поднимаете матрицу доступа: роли, гранты, схемы, сервисные аккаунты;
- отмечаете «опасные места» по типам: даты, строки, округления чисел;
- не полагаетесь на автоконвертацию без выборочной ручной проверки;
- планируете тесты: сравнение результатов, регресс, базовые замеры скорости.
Четвертая ошибка - вера, что конвертер «переведет все». Автоматизация помогает, но почти всегда остается слой ручной доработки: исключения, курсоры, пакетная архитектура, особенности транзакций.
Пятая - отсутствие плана тестирования. Без эталонных наборов данных и сценариев сравнения о расхождениях вы узнаете слишком поздно, когда исправления начинают ломать уже перенесенные части.
Короткий чеклист: готовы ли вы к старту
Перед тем как называть сроки и бюджет, проверьте базовые вещи. Этот чеклист помогает понять, насколько реальна ваша оценка и где вы рискуете «утонуть» в переписывании логики.
Начните с инвентаризации, но не ограничивайтесь выгрузкой списка объектов. Зафиксируйте владельцев и ответственных: кто подтверждает, что пакет, триггер или job действительно нужен, и кто объяснит бизнес-смысл.
Дальше отметьте критичные процессы. Часто проблема не в количестве кода, а во времени: ночные окна, месячные закрытия, интеграционные цепочки. Если расписания и пики нагрузки не обозначены, вы не сможете честно оценить риски.
Проведите быстрый фильтр сложности: какие объекты завязаны на нестандартные типы, внешние вызовы, цепочки зависимостей, привилегии, контекст сессии. Один «тяжелый» объект может стоить как десятки простых.
Практичный минимум, который должен быть готов:
- реестр объектов с владельцами и статусом (используется/сомнительно/можно убрать);
- карта критичных сценариев и окна выполнения джобов, включая «крайние даты» (закрытие месяца, отчеты);
- список объектов высокой сложности с причиной (зависимости, внешние вызовы, особенности Oracle);
- согласованные допущения и критерии приемки: что считается «одинаково работает», какие требования по скорости и отказоустойчивости;
- план пилота на 1-2 типовых модуля с метриками успеха.
Пример: если пилотный модуль содержит 2 пакета, 10 триггеров и 3 джоба, но один пакет тянет за собой интеграцию и много исключений, его лучше выделить отдельно. Тогда пилот покажет реальную скорость переписывания и тестирования, а не «среднюю температуру» по базе.
Пример сценария оценки на небольшом модуле
Представим модуль учетной системы: днем пользователи вводят операции, а ночью запускаются расчеты (начисления, сверки, формирование витрин для отчетов). Контроль качества данных частично зашит в триггеры: проверяются лимиты, статусы, запрет на удаление, автозаполнение полей.
На первичной инвентаризации нашли: 3 пакета PL/SQL (средние по размеру), 20 триггеров (сложные), 5 джобов (средние). Здесь важны не только количества, но и характер логики. «Средний» пакет, который просто читает и пишет таблицы, обычно переносится быстрее, чем триггер, который дергает другие объекты и полагается на особенности Oracle.
Быстрый расчет можно построить так: пакетам дать базовую сложность, триггерам повысить вес из-за скрытых правил и побочных эффектов, джобам оценить переносимость расписаний и зависимостей. Затем задайте бизнесу несколько вопросов, чтобы не тратить время на то, что можно упростить:
- какие 2-3 отчета и расчета критичны в первые недели после запуска;
- есть ли правила, которые можно перенести из триггеров в приложение или в явные процедуры;
- допустимы ли изменения ночного окна и порядка выполнения расчетов;
- какие ошибки сейчас «ловятся» триггерами и как это проверяют пользователи.
После уточнений оценку удобно сразу превратить в мини-план, где видны быстрые шаги и рисковые зоны. Например, начать с пилота на одном ночном расчете и паре таблиц, параллельно готовить перенос данных.
- пилот: перенос 1 пакета + 2-3 ключевых триггера, прогон контрольных сценариев;
- перенос данных: правила загрузки, сверка итогов, откатный план;
- переписывание логики: оставшиеся пакеты, триггеры, перенос джобов и расписаний;
- тесты: регресс по критичным отчетам, нагрузка ночного окна, приемка с бизнесом.
Так заранее видно, что 20 сложных триггеров, скорее всего, съедят больше времени, чем 3 «средних» пакета, и можно проверить требования до начала массового переписывания.
Следующие шаги: от первичной оценки к плану проекта
После первичной оценки важно быстро превратить цифры и заметки в рабочий план. Задача на этом этапе - зафиксировать результаты так, чтобы ими могли пользоваться и разработчики, и бизнес.
Удобный формат - один общий реестр инвентаря. Для каждого объекта (пакет, триггер, job, тип, view) запишите: модуль, краткое назначение, оценку сложности (S/M/L), ключевые риски (зависимости, сторонние утилиты, особенности Oracle), владельца логики и критерий готовности (тесты, отчеты, SLA).
Дальше выберите стратегию переноса, которая снижает неизвестность: сначала то, что дает максимум знаний о вашей кодовой базе. Обычно это сочетание бизнес-критичности и технических зависимостей.
Чтобы превратить оценку в план, зафиксируйте несколько шагов: разберите работы по модулям и зависимостям, отметьте блокирующие объекты, назначьте роли (разработчики, DBA, тестирование, владельцы процессов), согласуйте критерии приемки и запланируйте пилот на одном типовом модуле с временем на пересмотр оценок.
Если на этапе планирования нужен партнер по инфраструктуре и сопровождению, это можно обсуждать с GSE.kz (gse.kz): как системный интегратор компания помогает спроектировать контур под PostgreSQL и организовать поддержку, включая круглосуточный сервис для критичных систем.