Реплицировать столбцы идентичности

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

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

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

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

Примечание.

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

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

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

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

    Примечание.

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

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

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

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

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

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

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

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

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

При пакетной вставке большого объёма триггер репликации срабатывает только один раз, а не для каждой вставляемой строки. Это может привести к сбою оператора INSERT, если диапазон значений IDENTITY исчерпывается при выполнении крупной вставки, например в инструкции 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>.

    Примечание.

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