04 Занятие 04: Установка и сопровождение / Миграция
Эта страница извлечена из официального PDF в нативный Markdown. Текст слайдов, код и комментарии сохранены в порядке чтения; исходные PDF и HTML остаются эталоном макета. HTML source: pgpro_04_migration.html Archive: PGPRO-handouts-16.zip Страниц PDF: 22
Page 1: Установка и сопровождение / Миграция
Авторские права
© Postgres Professional, 2023–2026 Авторы: Алексей Береснев, Илья Баштанов, Павел Толмачев, Игорь Гнатюк Фото: Олег Бартунов (монастырь Пху и пик Бхрикути, Непал)
Использование материалов курса
Некоммерческое использование материалов курса (презентации, демонстрации) разрешается без ограничений. Коммерческое использование возможно только с письменного разрешения компании Postgres Professional. Запрещается внесение изменений в материалы курса.
Обратная связь
Отзывы, замечания и предложения направляйте по адресу: edu@postgrespro.ru
Отказ от ответственности
Компания Postgres Professional не несет никакой ответственности за любые повреждения и убытки, включая потерю дохода, нанесенные прямым или непрямым, специальным или случайным использованием материалов курса. Компания Postgres Professional не предоставляет каких-либо гарантий на материалы курса. Материалы курса предоставляются на основе принципа «как есть» и компания Postgres Professional не обязана предоставлять сопровождение, поддержку, обновления, расширения и изменения.
Page 2: Темы
- Варианты и сложности миграции
- Миграция данных
- Миграция объектов бизнес-логики
- Реализация системных пакетов из Oracle
- Пакеты в Postgres Pro Enterprise
- Утилита ora2pgpro
Page 3: Варианты и сложности
Миграция на Postgres Pro Enterprise с других СУБД
- Oracle
- MS SQL Server
- MySQL
- PostgreSQL
- Задачи и сложности
- перенос схемы и данных: различия в типах, время переноса больших
- объемов
- перенос кода: хранимый код может сильно зависеть от СУБД
- перенос нестандартного функционала
Комментарии преподавателя
Миграция, то есть переход с одной системы баз данных на другую, — сложная задача с огромным количеством трудностей и нюансов, перечислить которые здесь не представляется возможным. Упомянем главные:
● несоответствие типов переносимых данных в исходной и целевой СУБД;
● время переноса серьезных объемов данных может оказаться достаточно большим;
● трудоемкость переноса хранимого кода, в том числе из-за различий языков и их диалектов;
● сложность переноса функционала, зависящего от СУБД (например такого, как автономные транзакции и пакеты из СУБД Oracle).
Применительно к предмету курса, одним из популярных вариантов является миграция из Oracle в Postgres Pro Enterprise. Рассмотрению этой задачи посвящена почти вся эта тема.
https://postgrespro.ru/docs/enterprise/16/pgpro-migration-tools
Page 4: Миграция объектов
Объекты SQL
- таблицы, индексы, представления, последовательности
- схемы
- Подпрограммы
- процедуры, функции, триггеры
- Другие объекты и нестандартный функционал
- пакеты
- автономные транзакции
Комментарии преподавателя
Миграция стандартных объектов SQL, таких как таблицы, индексы, представления и последовательности, относительно проста и поддается автоматизации.
Сложной может оказаться миграция хранимого кода — функций, процедур, триггеров — из-за разнообразия логики, а также различий в используемых языках и модулях.
Миграция других объектов — тоже сложная задача, поскольку реализация многих из них в Postgres Pro Enterprise может отличаться от других СУБД или вовсе не иметь аналогов. Например, пакеты, которые появились в версии 15, не являются прямыми аналогами пакетов Oracle — их синтаксис и возможности различаются.
Есть большое количество сторонних решений, автоматизирующих процесс миграции; они экономят усилия и снижают количество ошибок. Но в целом задача очень многообразна и сложна, поэтому автоматизировать ее полностью не представляется возможным.
Page 5: Миграция данных
SQL
- выгрузка + psql
- Обертки сторонних данных
- универсальные для СУБД: ODBC, JDBC
- для реляционных СУБД: Oracle (oracle_fdw), MS SQL (tds_fdw), MySQL,
- DB2, SQLite
- для NoSQL-СУБД: MongoDB, Redis, Cassandra
- файловые: file_fdw, CSV, JSON
Комментарии преподавателя
При миграции данных из других СУБД можно использовать SQL как промежуточный формат. Конечно, это самый универсальный подход, но на практике при значительных объемах данных он неприменим. К тому же из-за разницы в диалектах SQL может потребоваться дополнительное преобразование данных и команд.
Для удобства работы со скриптами, часто применяемыми при такой миграции, утилита psql в Postgres Pro Enterprise может передавать им при вызове именованные и позиционные параметры.
https://postgrespro.ru/docs/enterprise/16/app-psql#APP-PSQL-META-COM MAND-INCLUDE
Дополнительные удобства и более высокую производительность можно получить, используя механизм оберток сторонних данных (foreign data wrappers), встроенный в PostgreSQL и позволяющий обращаться к внешним данным как к локальным таблицам. Штатная обертка file_fdw позволяет читать данные из файлов различных форматов. В составе дистрибутива Postgres Pro Enterprise присутствует пакет oracle-fdw-ent-16 с расширением oracle_fdw, устанавливающий одноименную обертку, и пакет tds-fdw-ent-16 для подключения к Microsoft SQL Server. Помимо этого, существует множество сторонних оберток для различных СУБД и форматов файлов.
https://wiki.postgresql.org/wiki/Foreign\_data\_wrappers
Page 6: Параметры при вызове скрипта в утилите psql
Начиная с 15-й версии Postgres Pro Enterprise поддерживается передача именованных и позиционных параметров при вызове скрипта в утилите psql. Если передается «имя=значение», создается переменная с указанным именем. Если указано только значение, оно присваивается позиционной переменной с именем PSQL_ARG1, PSQL_ARG2 и т. д. Именованные и позиционные параметры можно использовать одновременно. Для демонстрации создадим файл example.sql:
Перед выполнением запроса скрипт выводит значения трех переменных, переданных через параметры. Подразумевается, что первые два параметра будут именованными, а последний — позиционным. Запустим скрипт из psql:
Page 7: Системные пакеты Oracle
Расширение orafce
- функции, представления
- пакеты dbms_output, dbms_sql, dbms_pipe, dbms_alert, dbms_utility,
- dbms_assert, utl_file
- и др.
- Реализация других системных пакетов Oracle
- dbms_lob, dbms_application_info
- utl_mail, utl_smtp, utl_http
Комментарии преподавателя
В дистрибутив Postgres Pro Enterprise включен пакет orafce-ent-16, устанавливающий расширение orafce. Оно добавляет в базу данных Postgres Pro Enterprise объекты, аналогичные объектам СУБД Oracle, что сильно упрощает перенос процедурной логики.
https://github.com/orafce/orafce
Несколько расширений, эмулирующих другие системные пакеты Oracle, поставляются в отдельном пакете pgpro-orautl-ent-16:
● utl_mail — управление электронными письмами;
● utl_smtp — отправка электронных писем из PL/pgSQL;
● utl_http — выполнение HTTP-вызовов из SQL и PL/pgSQL.
https://postgrespro.ru/docs/enterprise/16/utl-mail
https://postgrespro.ru/docs/enterprise/16/utl-smtp
https://postgrespro.ru/docs/enterprise/16/utl-http
Еще два расширения добавлены в состав Postgres Pro Enterprise как стандартные и включены в основной пакет:
● dbms_lob — работа с большими объектами: BLOB, CLOB, BFILE и временными LOB;
● pgpro_application_info — реализация пакета dbms_application_info.
https://postgrespro.ru/docs/enterprise/16/dbms-lob
https://postgrespro.ru/docs/enterprise/16/pgpro-application-info
Page 8: Системные пакеты Oracle
Для примера рассмотрим работу с расширением pgpro_application_info, возможности которого можно использовать для анализа производительности и отладки приложений. Расширение содержит ряд подпрограмм, позволяющих приложениям сообщать о своем состоянии и ходе выполнения. Доступ к этой информации осуществляется через представления. Начнем с установки расширения:
Необходима перезагрузка экземпляра:
Добавим расширение в базу данных.
В транзакции первого сеанса будем вызывать процедуры из расширения pgpro_application_info: set_client_info — задает информацию о клиенте, например его название и/или описание; set_module — передает имя выполняемого в данный момент модуля (либо подпрограммы) и действие в нем; set_action — передает название выполняющегося действия в текущем модуле. Во втором сеансе будем проверять состояние первого, используя представление v_session того же расширения:
Первый сеанс:
Второй сеанс:
Обратите внимание, что расширение работает нетранзакционно — в ряде случаев это может оказаться удобным.
Page 9: Page 9
Откатим транзакцию в первом сеансе:
Page 10: Пакеты
{#source-figure-010 caption=“Source slide page 10: Пакеты”}
Комментарии преподавателя
Пакеты в Oracle позволяют сгруппировать логически связанные объекты (подпрограммы, переменные, типы данных, курсоры и т. п.). Пакет состоит из спецификации (объявления публичных элементов, доступных извне пакета) и тела (реализации подпрограмм, объявленных в спецификации, и внутренних элементов, доступных только внутри пакета). Спецификация определяет интерфейс пакета, а тело рассматривается как черный ящик — изменение реализации не влияет на пользователей пакета.
Спецификация и тело пакета — объекты базы данных Oracle.
Пакетные переменные и курсоры образуют состояние, свое для каждого сеанса, в котором используется пакет.
В теле пакета может находиться секция инициализации пакета — код, который выполняется один раз при первом обращении к пакету. С ее помощью можно задать начальное состояние, например, установить значения пакетных переменных.
В PostgreSQL аналогичной цели — группировке логически связанных объектов — служат схемы. Однако схема не имеет переменных и состояния, что очень сильно усложняет миграцию. Поэтому в Postgres Pro Enterprise реализован основной функционал пакетов. Он не повторяет пакеты Oracle синтаксически, а построен на основе схем.
https://postgrespro.ru/docs/enterprise/16/packages-overview
Page 11: Пакеты
Схема с функцией инициализации
- Состояние
- объявленные в __init__ переменные
- Аналог спецификации
- заголовки публичных подпрограмм
- типы данных
- #export-переменные из __init__ (по умолчанию все)
- Аналог тела
- публичные подпрограммы
- внутренние #private-подпрограммы
Комментарии преподавателя
Пакет в PostgresPro Enterprise — это схема, организованная специальным образом. Сначала в схеме создается функция с именем __init__ – функция инициализации.
Все переменные, объявленные в этой функции, становятся частью состояния пакета. По умолчанию все переменные будут публичными, то есть доступны снаружи пакета из подпрограмм, помеченных модификатором #import. Но можно сделать публичными только часть переменных, упомянув их в модификаторе #export, тогда все остальные будут доступны только из подпрограмм пакета. Обращаться к переменным пакета извне нужно по квалифицированному имени: имя-пакета.имя-переменной.
Затем создаются пакетные подпрограммы – их помечают модификатором #package. По умолчанию такие подпрограммы будут публичными. Если же подпрограмма служит только для внутренних нужд пакета, ее следует пометить модификатором #private.
При обращении к любой пакетной подпрограмме вызывается функция инициализации, которая формирует состояние пакета. Сбросить его можно вызовом функции инициализации или plpgsql_reset_packages (это аналог DBMS_SESSION.RESET_PACKAGES в Oracle).
В пакетах нет явного разделения на спецификацию и тело. По сути, спецификацию образуют заголовки публичных подпрограмм, публичные переменные и типы данных, входящие в схему. Аналогом тела будут все подпрограммы пакета: публичные и внутренние.
Пакет удобно создавать специальной командой CREATE PACKAGE.
https://postgrespro.ru/docs/enterprise/16/plpgsql-package
Page 12: Пакеты
Создадим пакет, предоставляющий локальный для сеанса счетчик:
При первом обращении к пакету выполняется функция инициализации:
В другом сеансе отсчет начинается заново:
А в первом сеансе счетчик продолжает увеличиваться:
Пакеты в Postgres Pro Enterprise реализованы как схемы. Поэтому в списке схем можно увидеть и схему demo:
Page 13: Page 13
Список схем-пакетов можно получить запросом, выводящим схемы, в которых есть функция __init__:
Удалим пакет:
Page 14: Утилита ora2pgpro
Автоматизация миграции из Oracle
- Конвертация кода PL/SQL
- пакеты, функции и процедуры, триггеры
- автономные транзакции
- VARRAY, ассоциативные массивы
- Перенос схемы данных и объектов
- параллельная выгрузка и загрузка данных
- секционированные таблицы (по спискам и по диапазонам, подсекции)
- BLOB, пользовательские типы данных
- поддержка DBLINK, SYNONYM, DIRECTORY
- полнотекстовый поиск
- Oracle Spatial (пространственные данные)
Комментарии преподавателя
Утилита ora2pgpro предназначена для автоматизации конвертации кода и переноса объектов из СУБД Oracle в Postgres Pro Enterprise.
Утилита ora2pgpro создана на основе ora2pg:
https://ora2pg.darold.net/documentation.html
Однако ora2pgpro существенно расширяет возможности ora2pg по переносу кода и типов данных, отсутствующих в PostgreSQL, но реализованных в Postgres Pro Enterprise. Помимо этого, в ora2pgpro устранены ошибки, найденные за время эксплуатации ora2pg.
Некоторые из поддерживаемых возможностей перечислены на слайде. Полный список и все настройки описаны в документации:
https://postgrespro.ru/docs/ora2pgpro/26/index
Для работы утилиты требуется Oracle Instant Client Package.
Утилита ora2pgpro не поддерживается на платформе ARM64 (MacBook с процессором Apple Silicon) и в виртуальной машине курса для этой платформы отсутствует.
Page 15: Утилита ora2pgpro
{#source-figure-015 caption=“Source slide page 15: Утилита ora2pgpro”}
Комментарии преподавателя
Утилита ora2pgpro подключается к БД Oracle, извлекает из нее структуру базы, данные и хранимый код (все вместе или по частям), и генерирует SQL-скрипты, которые потом можно загрузить в Postgres Pro Enterprise с помощью psql. В простых случаях, не требующих ручных правок, можно сформировать объекты напрямую в базе Postgres Pro Enterprise.
Утилита управляется директивами, которые позволяют переименовывать таблицы и столбцы в схеме данных, заменять типы данных (например, CHAR(1) на boolean, если он используется для логических значений) и т. д.
Для работы с хранимым кодом (пакетами, процедурами и функциями, триггерами) в утилиту добавлен транслятор, который разбирает код PL/SQL, строит дерево разбора и генерирует по нему код PL/pgSQL, используя все возможности, предоставляемые Postgres Pro Enterprise для совместимости с Oracle.
Page 16: ora2pgpro
Утилита ora2pgpro уже установлена в виртуальной машине курса:
Утилита может работать без подключения к БД Oracle, если необходимые данные заранее выгружены в файлы. Создадим каталог, в котором будут находиться исходные данные для конвертации:
Поместим в него два скрипта, описывающие простой пакет Oracle:
Спецификация и тело пакета располагаются в подкаталоге sources каталога, который мы укажем утилите. В этот же каталог утилита выведет результаты своей работы.
Утилите также потребуется конфигурационный файл, в котором указываются параметры-директивы, управляющие ее работой и описывающие подключение к базам Oracle и Postgres Pro. Мы собираемся запустить утилиту в локальном режиме, поэтому не будем указывать параметры подключения к базе данных Oracle и файл будет коротким:
При запуске указываем тип экспорта PACKAGE (пакеты) и пути к каталогу миграции и к конфигурационному файлу:
Сценарий — результат преобразования схемы — будет записан в файл:
Page 17: Page 17
Выполним этот файл с помощью psql:
В базе данных появилась новая схема-пакет с необходимыми функциями:
Page 18: Итоги
Миграция с других СУБД — сложная задача
- Postgres Pro Enterprise облегчает миграцию с Oracle
- функционал пакетов
- утилита ora2pgpro для автоматизации переноса данных и кода
- аналоги системных пакетов Oracle
- параметры при вызове скрипта в утилите psql
Page 19: Практика
- Создайте базу данных и добавьте в нее расширение orafce. 2. Какие схемы появились после загрузки расширения? 3. Изучите возможности функции dbms_random.string.
Комментарии преподавателя
Пакет orafce-ent-16 уже установлен в виртуальной машине.
С документацией по orafce можно ознакомиться в репозитории
https://github.com/orafce/orafce
Page 20: 1. Добавление расширения orafce
Создадим базу данных pgpro_migration и подключимся к ней:
Расширение orafce распространяется в отдельном пакете orafce-ent-16, который уже установлен в виртуальной машине курса. Поэтому для установки расширения в базу данных достаточно выполнить команду CREATE EXTENSION:
2. Проверка доступных функций
Расширение orafce представляет реализации многих функций, которые существуют в СУБД Oracle, но отсутствуют (или реализованы по-другому) в Postgres Pro. Функции каждого из пакетов располагаются в отдельных схемах:
3. Функция dbms\_random.string
Пакет dbms_random предназначен для генерации случайных чисел и строк. Посмотрим, какие функции в него входят:
Page 21: Page 21
Функция string возвращает случайные строки. Ее первый параметр однобуквенный, он отвечает за вид возвращаемого значения: U/u — строка в верхнем регистре; L/l — строка в нижнем регистре; A/a — строка в смешанном регистре; X/x — строка из буквенно-цифровых символов в верхнем регистре; P/p — строка из любых печатных символов в смешанном регистре. Второй параметр управляет длиной строки:
Уборка
Удалим созданную базу данных.