Недавно мы написали о том, насколько экономически разумно «переезжать» с Oracle на PostgreSQL. В этом материале хотели бы поделиться практическим опытом, как осуществить миграцию небольшой СУБД, и какие подводные камни вас могут ожидать при этом.
Трудности перевода
Один из наших крупных клиентов — российский банк — захотел мигрировать небольшую типовую базу данных с Oracle на Postgres. В целом, забегая вперед, можно утверждать, что миграция прошла в штатном режиме, однако мы столкнулись с несколькими важными нюансами, которые рекомендуем учитывать коллегам.
Основная проблема, возникшая при переезде, была связана с mview. В нем была прописана функция regexp_replace. Характерно, что в Oracle она организована по одному принципу, а в PostgreSQL — совсем иначе. Однако функция в обоих СУБД называется одинаково, и из-за этого вывод запроса был некорректным. Нам пришлось проявить смекалку в поисках альтернативного варианта. И он нашелся! Речь идет о расширении под Postgres, которое называется orafce. Все бы было хорошо, но у этого расширения есть определенный нюанс, из-за которого нам надо было немного переписывать код, добавив в эту функцию «oracle.». При помощи orafce можно успешно использовать операторы дат Oracle в Postgres. Более подробно, как использовать это расширение, можно почитать по ссылке https://github.com/orafce/orafce. Так, в решении нашей задачи пришлось изменить в выгруженной схеме smallint на Boolean, поскольку по умолчанию для логического типа данных в схеме oracle использовался NUMBER(1).
Как мы действовали
Ниже последовательность наших действий при миграции схемы в хронологическом порядке.
Устанавливаем ora2pg и необходимые компоненты:
rpm -ivh oracle-instantclient12.2-basic-12.2.0.1.0-1.x86_64.rpm
rpm -ivh oracle-instantclient12.2-devel-12.2.0.1.0-1.x86_64.rpm
rpm -ivh oracle-instantclient12.2-jdbc-12.2.0.1.0-1.x86_64.rpm
rpm -ivh oracle-instantclient12.2-sqlplus-12.2.0.1.0-1.x86_64.rpm
yum install -y wget
wget https://yum.oracle.com/RPM-GPG-KEY-oracle-ol7 -O /etc/pki/rpm-gpg/RPM-GPG-KEY-oracle
yum install -y perl perl-CPAN perl-DBI perl-Time-HiRes perl-YAML perl-local-lib make gcc
yum install -y perl-App-cpanminus
cpanm CPAN::Config
cpanm CPAN::FirstTime
export LD_LIBRARY_PATH=/usr/lib/oracle/12.2/client64/lib
export ORACLE_HOME=/usr/lib/oracle/12.2/client64
perl -MCPAN -e 'install DBD::Oracle'
perl -MCPAN -e 'install DBD::Pg'
tar zxf ora2pg-23.1.tar.gz && cd ora2pg-21.1 && perl Makefile.PL && make && make install
ora2pg --project_base /migration/ --init_project test_project
Изменяем config созданного проекта. Редактируем подключение к Oracle:
ORACLE_DSN dbi:Oracle:host=*****;sid=***;port=1521
ORACLE_USER *****
ORACLE_PWD *****
Редактируем подключение к Postgres:
PG_DSN dbi:Pg:dbname=***;host=*****;port=5432
PG_USER postgres
PG_PWD *****
Указываем схему в Oracle и предполагаемую схему в Postgres:
SCHEMA ****
PG_SCHEMA ****
ora2pg -t SHOW_TABLE -c config/ora2pg.conf
Остальные настройки конфигурации, чтобы не повторяться, можно легко найти в документации к ora2pg.
Далее редактируем pg_hba и перезапускаем Postgres:
host all all 0.0.0.0/0 md5
systemctl restart postgresql-14
Проверяем подключение к схеме в базе Oracle и оцениваем миграцию:
ora2pg -t SHOW_TABLE -c config/ora2pg.conf
ora2pg -t SHOW_REPORT --estimate_cost -c config/ora2pg.conf export_schema.sh
Важно, что данные команды мы запускали в главной папке проекта. Далее запускаем ./export_schema.sh для выгрузки схемы.
Так как в нашем случае нужно было заранее использовать orafce для функции regexp_replace
, нам пришлось предварительно создать базу и пользователя в Postgres и загрузить расширение CREATE EXTENSION orafce.
После запуска ./import_all.sh -h localhost -d test -o test -U postgres –I
несколько раз возникали ошибки импорта, которые мы впоследствии исправили. В нашем варианте большинство ошибок было в коде mview.
Следующим шагом мы отдельно загружаем индексы, ограничения на первичные и внешние ключи и триггеры:
psql -h hostname -U username -d dbname < /migration/schema/tables/INDEXES_table.sql
psql -h hostname -U username -d dbname < /migration/schema/tables/CONSTRAINTS_table.sql
psql -h hostname -U username -d dbname < /migration/schema/tables/FKEYS_table.sql
psql -h hostname -U username -d dbname < /migration/schema/triggers/trigger.sql
Результат миграции. Стоит ли игра свеч?
После тестирования нам пришлось исправить некоторые проблемы в базе, например, рассинхронизацию sequence. Однако в целом миграция прошла успешно. И результат вместе с базой мы благополучно передали заказчику. Таким образом, если объем данных в таблицах исчисляется сотнями гигабайт, мы рекомендуем, при наличии ИТ-ресурсов, запускать миграцию при помощи ora2pg в несколько потоков. Подробная информация о том, как это сделать, есть в документации к ora2pg. Это действительно сильно ускоряет выгрузку и загрузку данных.
Схемы малого и среднего объема переносить на Postgres достаточно легко, и в текущее время эта задача особенно актуальна. Мы полагаем, что более крупные схемы в несколько терабайт разумнее мигрировать при помощи goldengate + ora2pg. При этом ora2pg – миграция структуры, а goldengate – миграция данных.
Делали ли вы миграции СУБД похожего объема? С какими трудностями пришлось столкнуться и, главное, как их удалось преодолеть?
Jet Service Team
Комментарии (11)
polar_yogi
13.09.2022 12:52+1Интересно услышать хоть какую-нибудь оценку - как изменилась скорость работы приложения после миграции данных, изменился ли объем БД после миграции, изменились ли требования к hardware.
uroborus_kulikov
13.09.2022 13:06+1Так как это была база малого объема скорость работы приложения практически не изменилась. Если бы предполагалась высокая нагрузка, использовались бы такие инструменты как pgbouncer и patroni. Часть нагрузки можно было бы снизить, отправив запросы чтения на slave. В любом случае, мы будем развиваться в данном направлении и при миграции крупных баз обязательно напишем.
PaulIsh
14.09.2022 16:08С Oracle на Pg не мигрировал. С Firebird мигрировал. Мигрировали с Fb 2.5 на Pg 10. По самому переносу данных и повторении структур - ничего особенного. Написали руками код миграции на node. Из особенностей только булевы поля добавились. А вот все триггеры, процедуры пришлось переписывать с нуля. И по ходу эксплуатации иногда ловить ошибки, что в Pg в триггерах нужно возвращать new, а в Fb не нужно и местами при ручном переносе это не замечалось.
На Pg был ощутимый рост скорости запросов при тех же индексах. Некоторые запросы ускорились в десятки раз (как помню, Firebird не очень любил not in () условия). Также на pg для аналитических запросов (отчеты, где кучи join-ов, аггрегация, подселекты) настроили master-slave репликацию, что позволило еще сильнее разгрузить оперативную базу.
Loskore
15.09.2022 18:16Мы в данный момент мигрируем с MS-SQL(T-Sql) на Pg12. И откровенно признаюсь, это просто адище в прямом смысле. Сам проект легаси, в котором накопилось бизнес логики за всё время существования (138 страдж процедур и 9 функций). И из-за этого каждый раз как в "первый раз": синтаксис отличается, очень важных языковых конструкций и команд(типа Merge) попросту нет. Запрос в Pg в отличии от T-Sql не может иметь переменных, и создание переменных типа "Table" не завезли (приходится заниматься колдунством ???? с массивами собственных типов) . Даже есть ньюансы в работе одной и той же ОРМ с СУБД от мягкомягких и pg. Так что, всём желаю крепко держать "бубен" с своих руках????, он нам ещё пригодиться.
edo1h
16.09.2022 06:51команд(типа Merge)
merge вроде бы будет в 15-ой версии, пока есть вот такое:
https://www.depesz.com/2015/05/10/waiting-for-9-5-add-support-for-insert-on-conflict-do-nothingupdate/
Isiirk
Обычно на Oraclе много кода бизнес-логики выполнено на PL/SQL в хранимых процедурах, я так понимаю вы перенесли только табличные данные?
uroborus_kulikov
Все верно.
Sleuthhound
Вероятно там было минимум кода, поэтому все так удачно.
На самом деле проблема тут не в переезде, а дальнейшей поддержки PostgreSQL, т.к. по Oracle очень много специалистов разного уровня и есть из чего выбрать, а по PostgreSQL специалистов очень мало и они дорогие, особенно те, кто знает внутрянку PostgreSQL.
uroborus_kulikov
Не совсем согласен в том что специалистов по postgresql мало...тут скорее вопрос в квалификации таких специалистов. И как раз такие малые проекты позволяют узнавать нюансы и постепенно увеличивать сложность для обучения, повышая тем самым квалификацию. Уже многие компании экспериментируют с миграцией Oracle и mssql на другие продукты opensorce. И эта тенденция как мне кажется будет только нарастать. А вот на что мигрировать, этот вопрос остаётся открытым. И зависит от специфики проекта.
Sleuthhound
Третий месяц ищем хотя бы джуна по постгрес, зп 160-200 т.р. , прособеседовали уж 5 человек и нииичего, по знаниям у них ооочень все вяло, но амбиции гора. Самое фиговое - люди просто не хотят учиться, денег хотят, а рвения к познаниям нуль.
FlyingDutchman
Видел оракловскую базу размером в 350TB (с приростом в 20-30TB/месяц), в которой было 0 логики и 0 строк PL/SQL кода. Упрощенное описание базы - просто огромное хранилище данных: объекты в BLOBах + описания объектов. Нельзя же считать бизнес-логикой автоматическое ежедневное создание date range партиций самим Ораклом? Ну да, 2-нодовый RAC с тремя Standby базами в разных датацентрах, ZFS-накопители, использующиеся для архивных read-only партиций и т.п.