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

ОБЛАСТЬ ПРИМЕНЕНИЯ: даSQL Server даБаза данных SQL Azure (только Управляемый экземпляр) нетAzure Synapse Analytics (хранилище данных SQL) нетParallel Data Warehouse APPLIES TO: yesSQL Server yesAzure SQL Database (Managed Instance only) noAzure Synapse Analytics (SQL DW) noParallel Data Warehouse

Когда столбцу назначается свойство IDENTITY, MicrosoftMicrosoft SQL ServerSQL Server автоматически создает последовательные номера для новых строк, вставляемых в таблицу, которая содержит столбец идентификаторов.When you assign an IDENTITY property to a column, MicrosoftMicrosoft SQL ServerSQL Server automatically generates sequential numbers for new rows inserted in the table containing the identity column. Дополнительные сведения см. в статье о свойстве IDENTITY (Transact-SQL).For more information, see IDENTITY (Property) (Transact-SQL). Так как столбцы идентификаторов могут быть включены как часть первичного ключа, важно исключить появление повторяющихся значений в столбцах идентификаторов.Because identity columns might be included as a part of the primary key, it is important to avoid duplicate values in the identity columns. Для использования столбцов идентификаторов в топологии репликации, имеющей обновления на нескольких узлах, все узлы топологии репликации должны использовать разные диапазоны значений идентификаторов, чтобы исключить появление повторяющихся идентификаторов.To use identity columns in a replication topology that has updates at more than one node, each node in the replication topology must use a different range of identity values, so that duplicates do not occur.

Например, для издателя может быть задано значение в диапазоне от 1 до 100, для подписчика А в диапазоне от 101 от 200, а для подписчика Б в диапазоне от 201 до 300.For example, the Publisher could be assigned the range 1-100, Subscriber A the range 101-200, and Subscriber B the range 201-300. Если строка вставляется в издателе и идентификатор имеет значение, равное, например, 65, это значение реплицируется на все подписчики.If a row is inserted at the Publisher and the identity value is, for example, 65, that value is replicated to each Subscriber. Когда репликация вставляет данные на каждый подписчик, она не увеличивает значение столбца идентификаторов в таблице подписчика; вместо этого вставляется буквенное значение 65.When replication inserts data at each Subscriber, it does not increment the identity column value in the Subscriber table; instead, the literal value 65 is inserted. Увеличение значения столбца идентификаторов вызывается только пользовательскими вставками, а не вставками агента репликации.Only user inserts, but not replication agent inserts cause the identity column value to be incremented.

Репликация обрабатывает столбцы идентификаторов в публикациях и подписках всех типов, что позволяет управлять столбцами вручную или разрешать механизму репликации автоматически управлять столбцами.Replication handles identity columns across all publication and subscription types, allowing you to manage the columns manually or have replication manage them automatically.

Примечание

Добавление столбца идентификаторов в опубликованную таблицу не поддерживается, поскольку это может привести к расхождению данных при репликации столбца на подписчик.Adding an identity column to a published table is not supported, because it can result in non-convergence when the column is replicated to the Subscriber. Значения в столбце идентификаторов на издателе зависят от порядка, в котором строки изменяемой таблицы хранятся физически.The values in the identity column at the Publisher depend on the order in which the rows for the affected table are physically stored. Строки могут храниться по-разному на подписчике. Поэтому значение для столбца идентификаторов может быть разным для одинаковых строк.The rows might be stored differently at the Subscriber; therefore the value for the identity column can be different for the same rows.

Указание режима управления диапазонами идентификаторовSpecifying an Identity Range Management Option

Репликация предоставляет три режима управления диапазонами идентификаторов.Replication offers three identity range management options:

  • Автоматический.Automatic. Используется для репликации слиянием и репликации транзакций с обновлениями на подписчике.Used for merge replication and transactional replication with updates at the Subscriber. Укажите диапазоны размера для издателя и подписчиков, и репликация будет автоматически управлять назначением новых диапазонов.Specify size ranges for the Publisher and Subscribers, and replication automatically manages the assignment of new ranges. Репликация устанавливает параметр NOT FOR REPLICATION для столбца идентификаторов на подписчике, чтобы увеличение значения на подписчике вызывалось только пользовательскими вставками.Replication sets the NOT FOR REPLICATION option on the identity column at the Subscriber, so that only user inserts cause the value to be incremented at the Subscriber.

    Примечание

    Для получения новых диапазонов подписчики должны синхронизироваться с издателем.Subscribers must synchronize with the Publisher to receive new ranges. Поскольку диапазоны идентификаторов назначаются подписчикам автоматически, существует возможность исчерпания всех диапазонов идентификаторов каким-либо подписчиком, если он будет многократно повторять запросы новых диапазонов.Because Subscribers are assigned identity ranges automatically, it is possible for any Subscriber to exhaust the entire supply of identity ranges if it repeatedly requests new ranges.

  • Вручную.Manual. Используется для репликации моментальных снимков и репликации транзакций без обновлений на подписчике, для одноранговой репликации транзакций или если приложение должно программно управлять диапазонами идентификаторов.Used for snapshot and transactional replication without updates at the Subscriber, peer-to-peer transactional replication, or if your application must control identity ranges programmatically. Если указывается ручной режим управления, следует обеспечить назначение диапазонов издателю и каждому подписчику, а также назначение новых диапазонов при использовании исходных диапазонов.If you specify manual management, you must ensure that ranges are assigned to the Publisher and each Subscriber and that new ranges are assigned if the initial ranges are used. Репликация устанавливает параметр NOT FOR REPLICATION для столбца идентификаторов на подписчике.Replication sets the NOT FOR REPLICATION option on the identity column at the Subscriber.

  • Нет.None. Этот режим рекомендуется только для обеспечения обратной совместимости с предыдущими версиями SQL ServerSQL Server и доступен только из интерфейса хранимой процедуры для публикаций транзакций.This option is recommended only for backwards compatibility with earlier versions of SQL ServerSQL Server and is available only from the stored procedure interface for transactional publications.

Сведения об указании варианта управления диапазонами идентификаторов см. в этой статье.To specify an identity range management option, see Manage Identity Columns.

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

Репликация слиянием и репликация транзакций используют разные методы для назначения диапазонов. Эти методы описаны в данном разделе.Merge replication and transactional replication use different methods for assigning ranges; these methods are described in this section.

Существует два типа диапазонов, которые необходимо учитывать при репликации столбцов идентификаторов: диапазоны, назначаемые издателю и подписчикам, и диапазон типа данных в столбце.There are two types of ranges to take into account when replicating identity columns: the ranges assigned to the Publisher and Subscribers, and the range of the data type in the column. Следующая таблица показывает доступные диапазоны для типов данных, обычно используемых в столбцах идентификаторов.The following table shows the ranges available for the data types typically used in identity columns. Диапазон используется во всех узлах топологии.The range is used across all nodes in a topology. Например, если используется smallint , начинающийся с 1 с шагом 1, максимальное количество вставок для издателя и всех подписчиков равно 32 767.For example, if you use smallint starting at 1 with an increment of 1, the maximum number of inserts is 32,767 for the Publisher and all Subscribers. Реальное число вставок зависит от наличия промежутков в используемых значениях и от использования порогового значения.The actual number of inserts depends on whether there are gaps in the values used and whether a threshold value is used. Дополнительные сведения о пороговых значениях см. в следующих разделах: «Репликация слиянием» и «Репликация транзакций с подписками, обновляемыми посредством очередей».For more information about thresholds, see the following sections "Merge Replication" and "Transactional Replication with Queued Updating Subscriptions".

Если издатель после вставки исчерпывает свой диапазон идентификаторов, он может автоматически назначить новый диапазон при условии, что вставка была выполнена членом предопределенной роли db_owner базы данных.If the Publisher exhausts its identity range after an insert, it can automatically assign a new range if the insert was performed by a member of the db_owner fixed database role. Если вставка была выполнена пользователем, не являющимся членом этой роли, следует выполнить sp_adjustpublisheridentityrange (Transact-SQL) от имени агента чтения журнала, агента слияния или пользователя, входящего в роль db_owner.If the insert was performed by a user not in that role, the Log Reader Agent, Merge Agent, or a user who is a member of the db_owner role must run sp_adjustpublisheridentityrange (Transact-SQL). Чтобы назначение нового диапазона для публикаций транзакций происходило автоматически, должен выполняться агент чтения журнала (по умолчанию агент функционирует в непрерывном режиме).For transactional publications, the Log Reader Agent must be running to automatically allocate a new range (the default is for the agent to run continuously).

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

Во время вставки большого пакета триггер репликации запускается только один раз, а не каждый раз при вставке строки.During a large batch insert the replication trigger is fired only once, not for each row of the insert. Это может привести к ошибке инструкции вставки, если диапазон идентификаторов исчерпан в ходе большой вставки, например при выполнении инструкции INSERT INTO .This can lead to a failure of the insert statement if an identity range is exhausted during an large insert, such as an INSERT INTO statement.

Тип данныхData type ДиапазонRange
tinyinttinyint Режимом автоматического управления не поддерживаетсяNot supported for automatic management
smallintsmallint от -2^15 (-32 768) до 2^15-1 (32 767)-2^15 (-32,768) to 2^15-1 (32,767)
intint от -2^31 (-2 147 483 648) до 2^31-1 (2 147 483 647)-2^31 (-2,147,483,648) to 2^31-1 (2,147,483,647)
bigintbigint от -2^63 (-9 223 372 036 854 775 808) до 2^63-1 (9 223 372 036 854 775 807)-2^63 (-9,223,372,036,854,775,808) to 2^63-1 (9,223,372,036,854,775,807)
decimal и numericdecimal and numeric от -10^38+1 до 10^38-1-10^38+1 through 10^38-1

Примечание

Сведения о том, как создать автоматически увеличивающееся числовое значение, которое может использоваться в нескольких таблицах или вызываться из приложений без ссылки на какие-либо таблицы, см. в разделе Порядковые номера.To create an automatically incrementing number that can be used in multiple tables or that can be called from applications without referencing any table, see Sequence Numbers.

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

Диапазоны идентификаторов управляются издателем и распространяются на подписчики агентом слияния (в иерархии переиздания диапазоны управляются корневым издателем и переиздающими подписчиками).Identity ranges are managed by the Publisher and propagated to Subscribers by the Merge Agent (in a republishing hierarchy, ranges are managed by the root Publisher and the republishers). Значения идентификаторов назначаются из пула на издателе.The identity values are assigned from a pool at the Publisher. Если вы добавляете в публикацию статью со столбцом идентификаторов с помощью мастера создания публикации или хранимой процедуры sp_addmergearticle (Transact-SQL), нужно указать значения следующих параметров.When you add an article with an identity column to a publication in the New Publication Wizard or by using sp_addmergearticle (Transact-SQL), you specify values for:

  • Параметр @identity_range, управляющий размером диапазона идентификаторов, первоначально назначаемым издателю и подписчикам с клиентскими подписками.The @identity_range parameter, which controls the identity range size initially allocated both to the Publisher and to Subscribers with client subscriptions.

    Примечание

    Для подписчиков, на которых выполняются предыдущие версии SQL ServerSQL Server, этот параметр (вместо параметра @pub_identity_range) также управляет размером диапазона идентификаторов на переиздающих подписчиках.For Subscribers running previous versions of SQL ServerSQL Server, this parameter (rather than the @pub_identity_range parameter) also controls the identity range size at republishing Subscribers.

  • Параметр @pub_identity_range, управляющий размером диапазона идентификаторов для переиздания, назначается подписчикам с серверными подписками (необходим для переиздания данных).The @pub_identity_range parameter, which controls the identity range size for republishing allocated to Subscribers with server subscriptions (required for republishing data). Все подписчики с серверными подписками получают диапазон для переиздания, даже если они реально не переиздают данные.All Subscribers with server subscriptions receive a range for republishing, even if they don't actually republish data.

  • Параметр @threshold, который используется, чтобы определить, когда для подписки на SQL Server CompactSQL Server Compact или предыдущую версию SQL ServerSQL Server необходим новый диапазон идентификаторов.The @threshold parameter, which is used to determine when a new range of identities is required for a subscription to SQL Server CompactSQL Server Compact or a previous version of SQL ServerSQL Server.

Например, можно было бы указать 10 000 для @identity_range и 500 000 для @pub_identity_range.For example, you could specify 10000 for @identity_range and 500000 for @pub_identity_range. Издателю и всем подписчикам, на которых запущена SQL Server 2005 (9.x)SQL Server 2005 (9.x) или более поздняя версия, включая подписчик с серверной подпиской, назначается основной диапазон 10 000.The Publisher and all Subscribers running SQL Server 2005 (9.x)SQL Server 2005 (9.x) or a later version, including the Subscriber with the server subscription, are assigned a primary range of 10000. Подписчику с серверной подпиской также назначается основной диапазон 500 000, который может использоваться подписчиками, которые синхронизируются с переиздающим подписчиком (для статей публикации на переиздающем подписчике необходимо также указать параметры @identity_range, @pub_identity_range и @threshold).The Subscriber with the server subscription is also assigned a primary range of 500000, which can be used by Subscribers that synchronize with the republishing Subscriber (you must also specify @identity_range, @pub_identity_range, and @threshold for the articles in the publication at the republishing Subscriber).

Каждый подписчик, использующий SQL Server 2005 (9.x)SQL Server 2005 (9.x) или более позднюю версию, также получает дополнительный диапазон идентификаторов.Each Subscriber running SQL Server 2005 (9.x)SQL Server 2005 (9.x) or a later version also receives a secondary identity range. Дополнительный диапазон равен по размеру основному диапазону. При исчерпании основного диапазона используется дополнительный диапазон, и агент слияния назначает подписчику новый диапазон.The secondary range is equal in size to the primary range; when the primary range is exhausted, the secondary range is used, and the Merge Agent assigns a new range to the Subscriber. Новый диапазон становится дополнительным диапазоном, и процесс продолжается по мере использования подписчиком значений идентификаторов.The new range becomes the secondary range, and the process continues as the Subscriber uses identity values.

Репликация транзакций с подписками посредством очередейTransactional Replication with Queued Updating Subscriptions

Диапазоны идентификаторов управляются распространителем и передаются на подписчики агентом распространителя.Identity ranges are managed by the Distributor and propagated to Subscribers by the Distribution Agent. Значения идентификаторов назначаются из пула на распространителе.The identity values are assigned from a pool at the Distributor. Размер пула основан на размере типа данных и приращении, используемом для столбца идентификаторов.The pool size is based on the size of the data type and the increment used for the identity column. Если вы добавляете в публикацию статью со столбцом идентификаторов с помощью мастера создания публикации или хранимой процедуры sp_addarticle (Transact-SQL), нужно указать значения следующих параметров.When you add an article with an identity column to a publication in the New Publication Wizard or by using sp_addarticle (Transact-SQL), you specify values for:

  • Параметр @identity_range, который управляет размером диапазона идентификаторов, первоначально назначаемого всем подписчикам.The @identity_range parameter, which controls the identity range size initially allocated to all Subscribers.

  • Параметр @pub_identity_range, который управляет размером диапазона идентификаторов, назначаемого издателю.The @pub_identity_range parameter, which controls the identity range size allocated to the Publisher.

  • Параметр @threshold, который используется для определения необходимости в новом диапазоне идентификаторов для подписки.The @threshold parameter, which is used to determine when a new range of identities is required for a subscription.

Например, можно было бы указать 10 000 для @pub_identity_range, 1000 для @identity_range (в предположении небольшого количества обновлений на подписчике) и 80 процентов для @threshold.For example, you could specify 10000 for @pub_identity_range, 1000 for @identity_range (assuming fewer updates at the Subscriber), and 80 percent for @threshold. После 800 вставок на подписчике (80 процентов от 1000) подписчику назначается новый диапазон.After 800 inserts at a Subscriber (80 percent of 1000), a Subscriber is assigned a new range. После 8000 вставок на издателе ему назначается новый диапазон.After 8000 inserts at the Publisher, the Publisher is assigned a new range. Когда назначается новый диапазон идентификаторов, появляется зазор в значениях диапазона идентификаторов в таблице.When a new range is assigned, there will be a gap in the identity range values in the table. При указании более высоких пороговых значений зазоры становятся меньше, но при этом уменьшается отказоустойчивость системы: если агент распространителя не может быть запущен по каким-либо причинам, подписчик может быстрее исчерпать диапазон доступных идентификаторов.Specifying a higher threshold results in smaller gaps, but the system is less fault-tolerant: if the Distribution Agent cannot run for some reason, a Subscriber could more easily run out of identities.

Назначение диапазонов для ручного управления диапазонами идентификаторовAssigning ranges for manual identity range management

Если указывается ручное управление диапазонами идентификаторов, следует убедиться, что издатель и каждый подписчик используют разные диапазоны идентификаторов.If you specify manual identity range management, you must ensure that the Publisher and each Subscriber use different identity ranges. Например, рассмотрим таблицу на издателе со столбцом идентификаторов, определенным как IDENTITY(1,1): столбец идентификаторов начинается с 1 и увеличивается с шагом 1 при каждой вставке строки.For example, consider a table at the Publisher with an identity column defined as IDENTITY(1,1): the identity column starts at 1 and is incremented by 1 each time a row is inserted. Если таблица на издателе имеет 5 000 строк и ожидается увеличение таблицы на протяжении существования приложения, издатель может использовать диапазон от 1 до 10 000.If the table at the Publisher has 5,000 rows, and you expect some growth in the table over the life of the application, the Publisher could use the range 1-10,000. При наличии двух подписчиков подписчик А может использовать диапазон от 10 001 до 20 000, а подписчик Б может использовать диапазон от 20 001 до 30 000.Given two Subscribers, Subscriber A could use 10,001-20,000, and Subscriber B could use 20,001-30,000.

После инициализации подписчика с помощью моментального снимка или иным способом выполните DBCC CHECKIDENT, чтобы назначить подписчику начальную точку для его диапазона идентификаторов.After a Subscriber is initialized with a snapshot or through another means, execute DBCC CHECKIDENT to assign the Subscriber a starting point for its identity range. Например, на подписчике А следовало бы выполнить DBCC CHECKIDENT('<TableName>','reseed',10001).For example, at Subscriber A, you would execute DBCC CHECKIDENT('<TableName>','reseed',10001). На подписчике B следовало бы выполнить CHECKIDENT('<TableName>','reseed',20001).At Subscriber B, you would execute CHECKIDENT('<TableName>','reseed',20001).

Чтобы назначить новые диапазоны издателю или подписчикам, выполните DBCC CHECKIDENT и укажите новое значение для повторной установки начальных значений таблицы.To assign new ranges to the Publisher or Subscribers, execute DBCC CHECKIDENT and specify a new value to reseed the table. Необходим какой-либо способ, чтобы определить, когда должен назначаться новый диапазон.You should have some way to determine when a new range must be assigned. Например, приложение могло бы иметь механизм, который обнаруживает, когда узел близок к исчерпыванию своего диапазона, и назначает новый диапазон, используя DBCC CHECKIDENT.For example, your application could have a mechanism that detects when a node is about to use up its range and assign a new range using DBCC CHECKIDENT. Можно также добавить проверочное ограничение, чтобы исключить добавление строки, если это приведет к использованию значения идентификатора, находящегося за пределами диапазона.You can also add a check constraint to ensure that a row cannot be added if it would cause an out of range identity value to be used.

Обработка диапазонов идентификаторов после восстановления базы данныхHandling Identity Ranges after a Database Restore

Если при восстановлении подписчика из резервной копии используется автоматическое управление диапазонами идентификаторов, новый диапазон значений идентификаторов запрашивается автоматически.If you are using automatic identity range management, when a Subscriber is restored from a backup, it automatically requests a new range of identity values. Если издатель восстанавливается из резервной копии, следует убедиться, что издателю назначен соответствующий диапазон.If a Publisher is restored from a backup, you must ensure that the Publisher is assigned an appropriate range. Для репликации слиянием назначьте новый диапазон с помощью sp_restoremergeidentityrange (Transact-SQL).For merge replication, assign a new range using sp_restoremergeidentityrange (Transact-SQL). Для репликации транзакций определите максимальное использованное значение и затем установите начальную точку для новых диапазонов.For transactional replication, determine the highest value that has been used and then set the starting point for new ranges. Используйте следующую процедуру после восстановления базы данных публикации.Use the following procedure after the publication database has been restored:

  1. Остановите все действия на всех подписчиках.Stop all activity on all Subscribers.

  2. Для каждой опубликованной таблицы, которая содержит столбец идентификаторов, выполните следующие действия.For each published table that includes an identity column:

    1. В базе данных подписок на каждом подписчике выполните IDENT_CURRENT('<TableName>').In the subscription database at each Subscriber, execute IDENT_CURRENT('<TableName>').

    2. Запишите максимальное значение, найденное среди всех подписчиков.Record the highest value found across all Subscribers.

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

    4. В базе данных публикаций на издателе выполните sp_adjustpublisheridentityrange <PublicationName>, <TableName>.In the publication database at the Publisher, execute sp_adjustpublisheridentityrange <PublicationName>, <TableName>.

    Примечание

    Если значение в столбце идентификаторов настроено на уменьшение, а не на увеличение, запишите минимальное найденное значение, а затем повторно задайте это значение в качестве начального условия.If the value in the identity column is set to decrement rather than increment, record the lowest value found, and then reseed with that value.

См. также:See Also

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