Подход к преобразованию последовательностей
Текущий подход к преобразованию:
Наша текущая логика миграции извлекает метаданные последовательности из таблицы системного каталога 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