CHANGE TRACKING MIN VALID VERSION: примеры (SQL)

Минимальная действительная версия для отслеживания изменений в SQL Server
Раздел: Функции разностного отслеживания изменений (Change Tracking)
CHANGE_TRACKING_MIN_VALID_VERSION(table_name): bigint

Описание функции CHANGE_TRACKING_MIN_VALID_VERSION

Функция CHANGE_TRACKING_MIN_VALID_VERSION возвращает минимальную версию, которая остается действительной для получения информации об изменениях из указанной таблицы с использованием системы отслеживания изменений (Change Tracking) в Microsoft SQL Server.

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

Аргументы функции

  • @table_id (тип INT) - Идентификатор объекта таблицы, для которой запрашивается минимальная действительная версия. Это обязательный параметр. Идентификатор можно получить с помощью функции OBJECT_ID.

Возвращаемое значение

Функция возвращает значение типа bigint. Это число представляет собой минимальную версию синхронизации, которая остается действительной для запрошенной таблицы. Если для таблицы не включено отслеживание изменений, функция возвращает NULL.

Примеры использования CHANGE_TRACKING_MIN_VALID_VERSION

Пример 1: Базовый вызов функции

Получение минимальной действительной версии для таблицы, участвующей в системе отслеживания изменений.

USE YourDatabase;
GO
DECLARE @min_valid_version bigint;
DECLARE @table_id int = OBJECT_ID(N'dbo.Employees');
SET @min_valid_version = CHANGE_TRACKING_MIN_VALID_VERSION(@table_id);
SELECT @min_valid_version AS MinValidVersion;
MinValidVersion
--------------
15

Пример 2: Проверка перед получением изменений

Типичный сценарий, когда клиентское приложение проверяет свою версию перед запросом изменений.

DECLARE @last_sync_version bigint = 10;
DECLARE @current_version bigint = CHANGE_TRACKING_CURRENT_VERSION();
DECLARE @min_valid_version bigint;
DECLARE @table_id int = OBJECT_ID(N'dbo.Products');
SET @min_valid_version = CHANGE_TRACKING_MIN_VALID_VERSION(@table_id);
IF (@last_sync_version < @min_valid_version)
BEGIN
    PRINT 'Требуется полная повторная синхронизация таблицы Products.';
END
ELSE
BEGIN
    PRINT 'Можно получить инкрементальные изменения.';
    -- Использование CHANGETABLE для получения изменений
END
Требуется полная повторная синхронизация таблицы Products.

Похожие функции в MS SQL Server

Для работы с системой отслеживания изменений (Change Tracking) существуют несколько связанных функций.

CHANGE_TRACKING_CURRENT_VERSION

Возвращает версию, связанную с последней зафиксированной транзакцией в базе данных. Это значение используется как текущая версия для последующих запросов изменений. Часто применяется вместе с CHANGE_TRACKING_MIN_VALID_VERSION для определения необходимости полной синхронизации.

CHANGETABLE

Это не функция, а табличная функция, которая возвращает сведения об изменениях для таблицы. Является основным инструментом для получения списка измененных строк после определенной версии. CHANGE_TRACKING_MIN_VALID_VERSION служит предварительной проверкой для ее корректной работы.

Предпочтительно сначала использовать CHANGE_TRACKING_MIN_VALID_VERSION для проверки состояния данных, и только затем, если проверка пройдена, выполнять запрос через CHANGETABLE. Это предотвращает ошибки и потерю данных в процессе синхронизации.

Альтернативы в других СУБД и языках

PostgreSQL: Логическая репликация и триггеры

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

-- Пример создания таблицы журнала и триггера в PostgreSQL
CREATE TABLE employee_changelog (
    id SERIAL PRIMARY KEY,
    operation CHAR(1),
    changed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    old_data JSONB,
    new_data JSONB
);

CREATE OR REPLACE FUNCTION log_employee_changes()
RETURNS TRIGGER AS $$
BEGIN
    INSERT INTO employee_changelog(operation, old_data, new_data)
    VALUES (TG_OP, row_to_json(OLD), row_to_json(NEW));
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER track_employee_changes
AFTER INSERT OR UPDATE OR DELETE ON employees
FOR EACH ROW EXECUTE FUNCTION log_employee_changes();

Oracle: Flashback Query и Change Data Capture (CDC)

Oracle предлагает технологию Flashback Query для запросов данных на момент времени в прошлом. Для постоянного отслеживания изменений используется Change Data Capture (CDC), которая более близка по концепции к SQL Server Change Tracking, но является отдельным комплексным решением.

MySQL: Бинарные логи (Binary Logs)

Отслеживание изменений часто реализуется через парсинг бинарных логов (binlog), которые содержат информацию обо всех операциях изменения данных. Это низкоуровневый подход, требующий внешних инструментов или библиотек (например, Debezium).

Ключевое отличие MS SQL Server Change Tracking заключается в его простоте и интеграции на уровне ядра СУБД, что обеспечивает минимальные накладные расходы по сравнению с некоторыми решениями на основе триггеров в других системах.

Типичные ошибки при использовании функции

Ошибка 1: Использование имени таблицы вместо ID объекта

Функция ожидает числовой идентификатор таблицы, а не ее имя.

-- Неправильно
SELECT CHANGE_TRACKING_MIN_VALID_VERSION('dbo.Employees');
Сообщение 8116, уровень 16, состояние 1, строка 1
Аргумент 1 для функции "CHANGE_TRACKING_MIN_VALID_VERSION" имеет недопустимый тип "varchar".
-- Правильно
DECLARE @table_id INT = OBJECT_ID('dbo.Employees');
SELECT CHANGE_TRACKING_MIN_VALID_VERSION(@table_id);

Ошибка 2: Запрос для таблицы с отключенным отслеживанием изменений

Если для таблицы не активировано отслеживание изменений, функция возвращает NULL. Неучет этого случая может привести к неожиданным результатам в логике приложения.

-- Для таблицы, где не выполнен: ALTER TABLE TableName ENABLE CHANGE_TRACKING
DECLARE @table_id INT = OBJECT_ID('dbo.UnTrackedTable');
SELECT CHANGE_TRACKING_MIN_VALID_VERSION(@table_id) AS MinVersion;
MinVersion
----------
NULL

Ошибка 3: Невнимательность к области действия (scope)

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

Изменения в последних версиях MS SQL Server

Со времени своего появления в SQL Server 2008, функция CHANGE_TRACKING_MIN_VALID_VERSION не претерпела значительных изменений в синтаксисе или основном поведении.

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

Рекомендуется следить за документацией по политикам очистки (CHANGE_TRACKING_AUTO_CLEANUP и CHANGE_RETENTION), так как они напрямую определяют, как долго хранится информация об изменениях и, следовательно, какое значение будет возвращать функция.

Расширенные примеры использования

Пример 1: Мониторинг состояния всех отслеживаемых таблиц

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

Пример sql
SELECT
    SCHEMA_NAME(t.schema_id) AS SchemaName,
    t.name AS TableName,
    CHANGE_TRACKING_MIN_VALID_VERSION(t.object_id) AS MinValidVersion,
    CHANGE_TRACKING_CURRENT_VERSION() AS CurrentVersion
FROM sys.tables t
WHERE CHANGE_TRACKING_MIN_VALID_VERSION(t.object_id) IS NOT NULL
ORDER BY SchemaName, TableName;
SchemaName TableName  MinValidVersion CurrentVersion
---------- ---------- --------------- --------------
dbo        Employees              15             42
dbo        Products               12             42
dbo        Orders                 38             42

Пример 2: Интеграция в процедуру синхронизации с резервным копированием

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

Пример sql
CREATE PROCEDURE dbo.SyncTableData
    @TableName sysname,
    @LastSyncVersion bigint OUTPUT
AS
BEGIN
    SET NOCOUNT ON;
    DECLARE @TableID int = OBJECT_ID(@TableName);
    DECLARE @MinValidVersion bigint;
    DECLARE @CurrentVersion bigint;
    SET @MinValidVersion = CHANGE_TRACKING_MIN_VALID_VERSION(@TableID);
    SET @CurrentVersion = CHANGE_TRACKING_CURRENT_VERSION();
    IF (@MinValidVersion IS NULL)
    BEGIN
        RAISERROR('Отслеживание изменений для таблицы не включено.', 16, 1);
        RETURN -1;
    END
    IF (@LastSyncVersion IS NULL OR @LastSyncVersion < @MinValidVersion)
    BEGIN
        -- Полная синхронизация
        PRINT 'Выполняется полная загрузка данных.';
        -- Код для полного считывания таблицы
        SET @LastSyncVersion = @CurrentVersion;
    END
    ELSE
    BEGIN
        -- Инкрементальная синхронизация
        PRINT 'Выполняется загрузка изменений.';
        SELECT
            ct.*,
            e.* -- Основные данные
        FROM CHANGETABLE(CHANGES @TableName, @LastSyncVersion) AS ct
        LEFT JOIN @TableName AS e ON ct.id = e.PrimaryKeyColumn;
        SET @LastSyncVersion = @CurrentVersion;
    END
    SELECT @LastSyncVersion AS NewSyncVersion;
END;

Пример 3: Сравнение версий для нескольких связанных таблиц

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

Пример sql
DECLARE @Tables TABLE (TableName sysname, TableID int);
INSERT INTO @Tables VALUES ('dbo.Orders', OBJECT_ID('dbo.Orders')), ('dbo.OrderDetails', OBJECT_ID('dbo.OrderDetails'));
DECLARE @ClientVersion bigint = 25;
DECLARE @GlobalMinValidVersion bigint = 0;
SELECT @GlobalMinValidVersion = MAX(CHANGE_TRACKING_MIN_VALID_VERSION(TableID))
FROM @Tables;
IF (@ClientVersion >= @GlobalMinValidVersion)
BEGIN
    PRINT 'Возможна инкрементальная синхронизация для всех таблиц.';
END
ELSE
BEGIN
    PRINT 'Требуется полная синхронизация хотя бы для одной таблицы.';
END

MS SQL CHANGE_TRACKING_MIN_VALID_VERSION function comments

En
CHANGE TRACKING MIN VALID VERSION Returns the minimum valid version for obtaining changes from a specified table