Попробовать бесплатно

Миграция перекрестных ссылок на базы данных

Как известно, PostgreSQL, в отличие от Sybase ASE и Microsoft SQL Server, не поддерживает нативные межбазовые (cross-database) ссылки.

При планировании миграции существует несколько возможных подходов к обработке баз данных, на которые ссылаются через границы БД:

  • миграция исходных баз данных как отдельных баз в одном экземпляре PostgreSQL или на разных инстансах
  • объединение нескольких баз данных в одну базу PostgreSQL с сохранением разделения на уровне схем
  • объединение нескольких баз данных в одну базу PostgreSQL и одну схему
  • временное оставление одной или нескольких баз данных в Sybase с обработкой межбазовых зависимостей на уровне приложения или интеграционного слоя

Все эти подходы могут быть реализованы или адаптированы в зависимости от конкретных требований и ограничений. Выбор стратегии в значительной степени определяется архитектурными, эксплуатационными и бизнес-факторами.

На практике чаще всего используются подходы №2 и №3.

Идентификация и отчётность по кросс-базовым ссылкам

Во время этапов оценки или конвертации Инструменты Конвертум обрабатывают межбазовые ссылки следующим образом:

  • инструмент Конвертум Сканер не выполняет явного сбора или отчётности по межбазовым ссылкам
  • Конвертум Мастер конвертирует такие ссылки неявно и не выделяет их в отдельную категорию

Уровень автоматической конвертации

Отчёт Конвертум Сканер не присваивает явного ранжирования межбазовым зависимостям. Однако на практике такие зависимости относятся к высокому уровню сложности.

При выборе стратегии объединения баз данных эти зависимости обычно обеспечивают примерно 50% автоматической конвертации, при этом оставшаяся часть требует ручной доработки.

Рекомендации по работе с межбазовыми зависимостями в PostgreSQL

Независимо от выбранного подхода миграции, настоятельно рекомендуется проверять весь код, сгенерированный инструментом. Инструкции по проверке приведены здесь.

В некоторых случаях кросс-базовые ссылки могут быть распознаны некорректно. В таких ситуациях может потребоваться ручная корректировка или настройка инструмента.

Также важно учитывать, что инструмент не всегда может автоматически получить определение объекта, если он находится в другой базе данных. В результате могут возникать проблемы, такие как несовместимость типов данных или отсутствие параметров типа REFCURSOR OUT в вызовах процедур.

Эти проблемы должны быть выявлены на этапе валидации и устранены с помощью целенаправленных ручных исправлений.

Необходимые настройки и функции

Миграция межбазовых ссылок обычно требует настройки определённого набора параметров конвертации. Эти параметры помогают адаптировать код под выбранную архитектуру PostgreSQL и минимизировать проблемы, связанные с межбазовыми зависимостями:

CONVERT_DATABASE_TO_SCHEMA 
CONVERT_DBLINK_TO_SCHEMA

подробную информацию про эти опции вы можете найти в документации о Разделе DDL А также будет полезным использовать маппинг схем: [Настройки маппинга схем] (https://www.convertum.ru/docs/knowledge-base/database-migration/tips-and-tricks/schema-mapping)

В любом случае, процесс включает создание Директории Проекта и ODBC-подключения для каждой мигрируемой базы данных.

Предположим, что у нас есть две базы данных: db1_db и db2_db. В базе данных db2_db существует процедура, которая ссылается на db1_db. Для их конвертации необходимо использовать два разных проекта с отдельными каталогами проектов.

cross_db_1

Каждый проект должен использовать собственное ODBC-подключение, указывающее на соответствующую исходную базу данных.

Оба проекта используют одинаковые настройки целевой базы данных, поэтому импорт выполняется в одну и ту же целевую базу данных.

Для обоих каталогов проектов необходимо задать следующие параметры в секции [DDL]:

EMPTY_SCHEMA = No
OUTSCHEMA = <имя исходной базы данных>

В результате, объекты из БД №1 будут помещены в схему db1_db, а объекты из БД №2 — в схему db2_db.

Дополнительно необходимо настроить следующие параметры в секции [DDL]:

CONVERT_DATABASE_TO_SCHEMA = Yes
CONVERT_DBLINK_TO_SCHEMA = Yes

cross_db_2

Результат конвертации:

DB #1 DB #2

create or replace procedure db1_db.proc1(INOUT SWV_RefCur refcursor default null, INOUT SWV_RefCur2 refcursor default null)
LANGUAGE plpgsql
   AS $$
   DECLARE
   v_t  VARCHAR(100);
BEGIN
   open SWV_RefCur for
   select CONCAT(COALESCE(p,''),COALESCE(v_t,'')) from db1_db.tab1 where 1 = 1;
   open SWV_RefCur2 for
   select CONCAT(COALESCE(v_t,''),COALESCE(p,'')) from db1_db.tab1 where 1 = 1;
END; $$;
create or replace FUNCTION db2_db.proc2()
RETURNS TABLE
(
   col VARCHAR
) LANGUAGE plpgsql
   AS $$
   DECLARE
   v_t  VARCHAR(100);
BEGIN
   CALL db1_db.proc1();
   
   return query
   select CONCAT(COALESCE(p,''),COALESCE(v_t,'')) from db1_db.tab1
   where id = cast('1' as INTEGER);
END; $$;

Как показано выше:

Процедура proc2 считается имеющей только один результирующий набор и была преобразована в функцию с RETURNS TABLE. Ссылки (references) указывают на корректные схемы. Тип данных столбца id был правильно определён как INTEGER, и в предложении WHERE было добавлено приведение типа (CAST) для корректной обработки различий в типах.

Однако вызов процедуры db1_db.proc1 в БД №2 не содержит параметров INOUT REFCURSOR.

Это происходит потому, что из первой базы данных невозможно определить, требуются ли эти REFCURSOR.

Для корректного определения и преобразования необходимо иметь доступ к полному определению процедуры из БД №1 в БД №2, чего наш инструмент не поддерживает.

Подобные случаи требуют ручной корректировки.

Ниже приведён вручную скорректированный вариант proc2:

create or replace procedure db2_db.proc2(
   INOUT SWV_RefCur refcursor default null,
   INOUT SWV_RefCur2 refcursor default null,
   INOUT SWV_RefCur3 refcursor default null
) LANGUAGE plpgsql
   AS $$
   DECLARE
   v_t  VARCHAR(100);
BEGIN
   CALL db1_db.proc1(SWV_RefCur, SWV_RefCur2);
   
   open SWV_RefCur3 for
   select CONCAT(COALESCE(p,''),COALESCE(v_t,'')) from db1_db.tab1
   where id = cast('1' as INTEGER);
END; $$;