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

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

Например, издателю можно назначить диапазон 1–100, подписчик A диапазон 101–200 и подписчик B диапазон 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, если диапазон значений идентификатора исчерпан при выполнении большой вставки, например инструкции 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.

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

Каждый подписчик под управлением SQL Server 2005 или более поздней версии также получает дополнительный диапазон удостоверений. Вторичный диапазон равен размеру первичного диапазона; Если основной диапазон исчерпан, используется дополнительный диапазон, а агент слияния назначает новый диапазон подписчику. Новый диапазон становится вторичным, и процесс продолжается, так как подписчик использует значения удостоверений.

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

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

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

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

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

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

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

Если указать управление диапазонами удостоверений вручную, необходимо убедиться, что издатель и каждый подписчик используют разные диапазоны удостоверений. Например, рассмотрим таблицу издателя со столбцом идентификаторов, определенным как IDENTITY(1,1): столбец идентификаторов начинается с 1 и увеличивается на 1 при каждой вставке строки. Если в таблице издателя имеется 5000 строк, и вы ожидаете, что таблица будет расширяться в процессе использования приложения, издатель может использовать диапазон от 1 до 10 000. Учитывая два подписчика, подписчик A может использовать 10 001-20 000, а подписчик B может использовать 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>.

    Замечание

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

См. также

BACKUP (Transact-SQL)
DBCC CHECKIDENT (Transact-SQL)
IDENT_CURRENT (Transact-SQL)
IDENTITY (Свойство) (Transact-SQL)
sp_adjustpublisheridentityrange (Transact-SQL)