Репликация столбцов идентификаторов

Область применения: SQL Server Управляемый экземпляр SQL Azure

При назначении свойства IDENTITY столбцу Microsoft SQL Server автоматически создает последовательные числа для новых строк, вставленных в таблицу, содержащую столбец удостоверения. Дополнительные сведения см. в разделе IDENTITY (Property) (Transact-SQL). Так как столбцы идентификаторов могут быть включены как часть первичного ключа, важно исключить появление повторяющихся значений в столбцах идентификаторов. Для использования столбцов идентификаторов в топологии репликации, имеющей обновления на нескольких узлах, все узлы топологии репликации должны использовать разные диапазоны значений идентификаторов, чтобы исключить появление повторяющихся идентификаторов.

Например, для издателя может быть задано значение в диапазоне от 1 до 100, для подписчика А в диапазоне от 101 от 200, а для подписчика Б в диапазоне от 201 до 300. Если строка вставляется в издателе и идентификатор имеет значение, равное, например, 65, это значение реплицируется на все подписчики. Когда репликация вставляет данные на каждый подписчик, она не увеличивает значение столбца идентификаторов в таблице подписчика; вместо этого вставляется буквенное значение 65. Увеличение значения столбца идентификаторов вызывается только пользовательскими вставками, а не вставками агента репликации.

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

Примечание.

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

Указание режима управления диапазонами идентификаторов

Репликация предоставляет три режима управления диапазонами идентификаторов.

  • Автоматически. Используется для репликации слиянием и репликации транзакций с обновлениями на подписчике. Укажите диапазоны размера для издателя и подписчиков, и репликация будет автоматически управлять назначением новых диапазонов. Репликация устанавливает параметр NOT FOR REPLICATION для столбца идентификаторов на подписчике, чтобы увеличение значения на подписчике вызывалось только пользовательскими вставками.

    Примечание.

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

  • Вручную. Используется для репликации моментальных снимков и репликации транзакций без обновлений на подписчике, для одноранговой репликации транзакций или если приложение должно программно управлять диапазонами идентификаторов. Если указывается ручной режим управления, следует обеспечить назначение диапазонов издателю и каждому подписчику, а также назначение новых диапазонов при использовании исходных диапазонов. Репликация устанавливает параметр NOT FOR REPLICATION для столбца идентификаторов на подписчике.

  • Нет. Этот параметр рекомендуется использовать только для обратной совместимости с более ранними версиями SQL Server и доступен только из интерфейса хранимой процедуры для публикаций транзакций.

Сведения об указании варианта управления диапазонами идентификаторов см. в этой статье.

Назначение диапазонов идентификаторов

Репликация слиянием и репликация транзакций используют разные методы для назначения диапазонов. Эти методы описаны в данном разделе.

Существует два типа диапазонов, которые необходимо учитывать при репликации столбцов идентификаторов: диапазоны, назначаемые издателю и подписчикам, и диапазон типа данных в столбце. Следующая таблица показывает доступные диапазоны для типов данных, обычно используемых в столбцах идентификаторов. Диапазон используется во всех узлах топологии. Например, если используется smallint , начинающийся с 1 с шагом 1, максимальное количество вставок для издателя и всех подписчиков равно 32 767. Реальное число вставок зависит от наличия промежутков в используемых значениях и от использования порогового значения. Дополнительные сведения о пороговых значениях см. в следующих разделах: «Репликация слиянием» и «Репликация транзакций с подписками, обновляемыми посредством очередей».

Если издатель после вставки исчерпывает свой диапазон идентификаторов, он может автоматически назначить новый диапазон при условии, что вставка была выполнена членом предопределенной роли db_owner базы данных. Если вставка была выполнена пользователем не в этой роли, агент чтения журналов, агент слияния или пользователь, являющийся членом роли db_owner, должен выполняться sp_adjustpublisheridentityrange (Transact-SQL). Чтобы назначение нового диапазона для публикаций транзакций происходило автоматически, должен выполняться агент чтения журнала (по умолчанию агент функционирует в непрерывном режиме).

Предупреждение

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

Тип данных Диапазон
tinyint Режимом автоматического управления не поддерживается
smallint от -2^15 (-32 768) до 2^15-1 (32 767)
int от -2^31 (-2 147 483 648) до 2^31-1 (2 147 483 647)
bigint от -2^63 (-9 223 372 036 854 775 808) до 2^63-1 (9 223 372 036 854 775 807)
decimal и numeric от -10^38+1 до 10^38-1

Примечание.

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

Репликация слиянием

Диапазоны идентификаторов управляются издателем и распространяются на подписчики агентом слияния (в иерархии переиздания диапазоны управляются корневым издателем и переиздающими подписчиками). Значения идентификаторов назначаются из пула на издателе. При добавлении статьи с столбцом удостоверений в публикацию в мастере создания публикаций или с помощью sp_addmergearticle (Transact-SQL) необходимо указать значения для следующих значений:

  • Параметр @identity_range, управляющий размером диапазона идентификаторов, первоначально назначаемым издателю и подписчикам с клиентскими подписками.

    Примечание.

    Для подписчиков, работающих с предыдущими версиями SQL Server, этот параметр (а не @pub_identity_range параметр) также управляет размером диапазона удостоверений при повторной публикации подписчиков.

  • Параметр @pub_identity_range, управляющий размером диапазона идентификаторов для переиздания, назначается подписчикам с серверными подписками (необходим для переиздания данных). Все подписчики с серверными подписками получают диапазон для переиздания, даже если они реально не переиздают данные.

  • Параметр @threshold , используемый для определения того, когда для подписки на SQL Server Compact или предыдущей версии SQL Server требуется новый диапазон удостоверений.

Например, можно было бы указать 10 000 для @identity_range и 500 000 для @pub_identity_range. Издатель и все подписчики под управлением SQL Server 2005 (9.x) или более поздней версии, включая подписчика с подпиской сервера, назначаются первичный диапазон 10000. Подписчику с серверной подпиской также назначается основной диапазон 500 000, который может использоваться подписчиками, которые синхронизируются с переиздающим подписчиком (для статей публикации на переиздающем подписчике необходимо также указать параметры @identity_range, @pub_identity_range и @threshold).

Каждый подписчик под управлением SQL Server 2005 (9.x) или более поздней версии также получает дополнительный диапазон удостоверений. Дополнительный диапазон равен по размеру основному диапазону. При исчерпании основного диапазона используется дополнительный диапазон, и агент слияния назначает подписчику новый диапазон. Новый диапазон становится дополнительным диапазоном, и процесс продолжается по мере использования подписчиком значений идентификаторов.

Репликация транзакций с подписками посредством очередей

Диапазоны идентификаторов управляются распространителем и передаются на подписчики агентом распространителя. Значения идентификаторов назначаются из пула на распространителе. Размер пула основан на размере типа данных и приращении, используемом для столбца идентификаторов. При добавлении статьи с столбцом удостоверений в публикацию в мастере создания публикаций или с помощью sp_addarticle (Transact-SQL) необходимо указать значения для следующих значений:

  • Параметр @identity_range, который управляет размером диапазона идентификаторов, первоначально назначаемого всем подписчикам.

  • Параметр @pub_identity_range, который управляет размером диапазона идентификаторов, назначаемого издателю.

  • Параметр @threshold, который используется для определения необходимости в новом диапазоне идентификаторов для подписки.

Например, можно было бы указать 10 000 для @pub_identity_range, 1000 для @identity_range (в предположении небольшого количества обновлений на подписчике) и 80 процентов для @threshold. После 800 вставок на подписчике (80 процентов от 1000) подписчику назначается новый диапазон. После 8000 вставок на издателе ему назначается новый диапазон. Когда назначается новый диапазон идентификаторов, появляется зазор в значениях диапазона идентификаторов в таблице. При указании более высоких пороговых значений зазоры становятся меньше, но при этом уменьшается отказоустойчивость системы: если агент распространителя не может быть запущен по каким-либо причинам, подписчик может быстрее исчерпать диапазон доступных идентификаторов.

Назначение диапазонов для ручного управления диапазонами идентификаторов

Если указывается ручное управление диапазонами идентификаторов, следует убедиться, что издатель и каждый подписчик используют разные диапазоны идентификаторов. Например, рассмотрим таблицу на издателе со столбцом идентификаторов, определенным как IDENTITY(1,1): столбец идентификаторов начинается с 1 и увеличивается с шагом 1 при каждой вставке строки. Если таблица на издателе имеет 5 000 строк и ожидается увеличение таблицы на протяжении существования приложения, издатель может использовать диапазон от 1 до 10 000. При наличии двух подписчиков подписчик А может использовать диапазон от 10 001 до 20 000, а подписчик Б может использовать диапазон от 20 001 до 30 000.

После инициализации подписчика с помощью моментального снимка или иным способом выполните DBCC CHECKIDENT, чтобы назначить подписчику начальную точку для его диапазона идентификаторов. Например, на подписчике А следовало бы выполнить DBCC CHECKIDENT('<TableName>','reseed',10001). На подписчике B следовало бы выполнить CHECKIDENT('<TableName>','reseed',20001).

Чтобы назначить новые диапазоны издателю или подписчикам, выполните DBCC CHECKIDENT и укажите новое значение для повторной установки начальных значений таблицы. Необходим какой-либо способ, чтобы определить, когда должен назначаться новый диапазон. Например, приложение могло бы иметь механизм, который обнаруживает, когда узел близок к исчерпыванию своего диапазона, и назначает новый диапазон, используя DBCC CHECKIDENT. Можно также добавить проверочное ограничение, чтобы исключить добавление строки, если это приведет к использованию значения идентификатора, находящегося за пределами диапазона.

Обработка диапазонов идентификаторов после восстановления базы данных

Если при восстановлении подписчика из резервной копии используется автоматическое управление диапазонами идентификаторов, новый диапазон значений идентификаторов запрашивается автоматически. Если издатель восстанавливается из резервной копии, следует убедиться, что издателю назначен соответствующий диапазон. Для репликации слиянием назначьте новый диапазон с помощью sp_restoremergeidentityrange (Transact-SQL). Для репликации транзакций определите максимальное использованное значение и затем установите начальную точку для новых диапазонов. Используйте следующую процедуру после восстановления базы данных публикации.

  1. Остановите все действия на всех подписчиках.

  2. Для каждой опубликованной таблицы, которая содержит столбец идентификаторов, выполните следующие действия.

    1. В базе данных подписок на каждом подписчике выполните IDENT_CURRENT('<TableName>').

    2. Запишите максимальное значение, найденное среди всех подписчиков.

    3. В базе данных публикаций на издателе выполните DBCC CHECKIDENT(<TableName>','reseed',<HighestValueFound+1>.

    4. В базе данных публикаций на издателе выполните sp_adjustpublisheridentityrange <PublicationName>, <TableName>.

    Примечание.

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