Подход к преобразованию последовательностей

Текущий подход к преобразованию:

Наша текущая логика миграции извлекает метаданные последовательности из таблицы системного каталога SYSIBM.SYSSEQUENCES в DB2.

Запрос, используемый нашим инструментом, выглядит следующим образом:

SELECT 
    RTRIM(SCHEMA) AS SEQUENCE_OWNER, 
    NAME AS SEQUENCE_NAME, 
    MINVALUE AS MIN_VALUES, 
    MAXVALUE AS MAX_VALUES, 
    INCREMENT AS INCREMENT_BY, 
    CYCLE AS CYCLE_FLAG, 
    ORDER AS ORDER_FLAG, 
    CACHE AS CACHE_SIZE, 
    START AS LAST_NUMBER 
FROM SYSIBM.SYSSEQUENCES 
WHERE RTRIM(SCHEMA) = '<schema_name>' 
  AND NAME = '<sequence_name>' AND SEQTYPE = 'S';
Ограничение:

В DB2 for z/OS системный каталог SYSIBM.SYSSEQUENCES не содержит столбца, в котором хранится последнее сгенерированное значение последовательности. Следовательно, невозможно получить эту информацию непосредственно из базы данных в процессе автоматической миграции.

В результате наш инструмент полагается на столбец START, который отражает только начальное значение, определенное при создании последовательности, а не текущее или последнее использованное значение. Это приводит к тому, что последнее использованное значение неправильно интерпретируется в процессе преобразования.

Ручное решение:

Чтобы привести поведение последовательности в PostgreSQL в соответствие с фактическим состоянием из DB2, мы предлагаем изменить начальное значение последовательности вручную.

Перед импортом данных в PostgreSQL определите последнее использованное значение последовательности в DB2 z/OS. Затем обновите сгенерированные SQL-файлы (например, <имя_последовательности>.sql), чтобы установить правильное начальное значение.

Например:

CREATE SEQUENCE SEQ_TEST
    INCREMENT BY 1
    START WITH <last_used_value + 1>
    MAXVALUE 2147483647
    MINVALUE 1
    NO CYCLE
    CACHE 20;

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


? Почему вы не можете использовать столбец MAXASSIGNEDVAL, доступный в таблице SYSIBM.SYSSEQUENCES

Ключевым моментом является то, что MAXASSIGNEDVAL отражает максимальное значение, которое было предварительно выделено или зарезервировано, а не последнее значение, выданное через NEXT VALUE FOR. Такое поведение особенно заметно, когда последовательности используют кэширование.

Посмотрите следующие примеры:

Пример 1: Кэшированная последовательность

CREATE SEQUENCE seq_test
    START WITH 1
    INCREMENT BY 1
    NO MAXVALUE
   NO CYCLE
    CACHE 20;

При создании DB2 сразу же резервирует кэш из 20 значений (от 1 до 20). Даже если мы выполняем только:

INSERT INTO tab_test_1 (id, name) VALUES (NEXT VALUE FOR seq_test, 'First');
INSERT INTO tab_test_1 (id, name) VALUES (NEXT VALUE FOR seq_test, 'Second');
INSERT INTO tab_test_1 (id, name) VALUES (NEXT VALUE FOR seq_test, 'Third');

MAXASSIGNEDVAL будет по-прежнему 20, что отражает верхнюю границу кэшированного блока, а не фактическое последнее использованное значение (которое в данном случае равно 3):

? Пример 2: Некэшированная последовательность

CREATE SEQUENCE seq_test_no_cache
    START WITH 1
    INCREMENT BY 10
    NO MAXVALUE
    NO CYCLE
    NOCACHE;
INSERT INTO tab_test_2 (id, name) VALUES (NEXT VALUE FOR seq_test_no_cache, 'First');
INSERT INTO tab_test_2 (id, name) VALUES (NEXT VALUE FOR seq_test_no_cache, 'Second');
INSERT INTO tab_test_2 (id, name) VALUES (NEXT VALUE FOR seq_test_no_cache, 'Third');

В этом случае значение в MAXASSIGNEDVAL будет обновляться более точно в соответствии с реальным использованием, поскольку каждый запрос NEXT VALUE FOR приводит к немедленному обновлению системного каталога:

Хотя столбец MAXASSIGNEDVAL может представлять текущее состояние последовательности, он ненадежно отражает последнее сгенерированное значение - особенно для кэшированных последовательностей. По этой причине наш инструмент не полагается на этот столбец во время миграции.

Чтобы обеспечить точное сохранение непрерывности последовательности, мы по-прежнему рекомендуем определять последнее использованное значение вручную перед импортом, а затем соответствующим образом корректировать значение START WITH в соответствующих операторах PostgreSQL CREATE SEQUENCE.

Если у вас есть вопросы, пожалуйста, обращайтесь в нашу службу поддержки: support@convertum.ru