SQL.RU
 client/server technologies
 Главная | Документация | Статьи | Книги | Форум | Блоги | Опросы | Гостевая | Рассылка | Работа | Поиск | FAQ |

Репликация слиянием - ручное управление диапазоном identity

ПУБЛИКАЦИИ  

По материалам статьи Paul Ibison: Merge Replication - Manual Range Handling
Перевод Маргариты Баскаковой

Для репликации транзакций и репликации моментальных снимков закономерно, что свойство identity, существующее на изданной таблице, не передается подписчику. Просто это не требуется, поскольку подписчик не предназначен для того, чтобы добавлять строки самостоятельно. Репликация слиянием, однако, предназначена для независимого, автономного добавления данных, и в этом случае, свойство identity будет передаваться. Поэтому возникает вопрос - как управлять диапазонами identity и гарантировать, что не будет наложений в значениях identity при синхронизации. Существует 2 варианта - автоматическое и ручное управление диапазонами. SQL Server может автоматически управлять диапазонами identity в репликации слиянием, но этот способ имеет плохую репутацию так как может повлечь за собой некоторые проблемы. Хотя верно то, что когда выделенный диапазон заканчивается раньше, чем произойдёт синхронизация, могут быть осложнения, в большинстве случаев их можно просто избежать: свойство identity накладывается на колонку с целочисленным типом данных int, который принимает значения в диапазоне от -2 147 483 648 до 2 147 483 647, тогда действительно, если у вас нет невероятно большого числа подписчиков, выбор большого диапазона значений на подписчике должен гарантировать, что выделенный диапазон не закончится. Однако в форумах часто задается вопрос - как вручную администрировать диапазоны identity и таким образом брать управление ими на себя. Эта статья представляет собой пошаговую инструкцию применения подобного алгоритма на практике.

(1) Метод без первоначальной синхронизации данных

Во-первых, выберите алгоритм, который Вы будете использовать для гарантии того, что диапазоны каждого из узлов не будут пересекаться. Существует несколько методов (см. сайт Michael Hotek's). Например, предположим, что Вы имеете издателя и трёх подписчиков. Издатель может иметь положительные четные номера, первый подписчик положительные нечетные номера, второй подписчик отрицательные четные номера, третий подписчик отрицательные нечетные номера. Используя этот метод, каждый узел имеет примерно один миллиард возможных значений.
Как только алгоритм выбран, удостоверьтесь перед публикацией таблицы, что начальное значение (Identity seed=2), и шаг приращения (Identity increment=2), установлены на издателе правильно [Рис. 1.1].

Рис. 1.1
[Рис. 1.1]

Если после публикации таблицы Вы попробуете изменить значение identity на издателе или подписчике это закончится сообщением об ошибке.

'tCompany' table
- Unable to modify table.
ODBC error: [Microsoft][ODBC SQL Server Driver][SQL Server]Cannot drop the table 'dbo.tCompany' because it is being used for replication.
ODBC error: [Microsoft][ODBC SQL Server Driver][SQL Server]] Невозможно удалить таблицу 'dbo.tCompany', так как она опубликована для репликации.

На издателе начальное значение (seed) и шаг приращения (increment) применяются, как только таблица опубликована, и это происходит раньше, чем у него появляется первый подписчик.
Теперь займёмся таблицей, участвующей в репликации слиянием. Убедитесь, что оставлен пустым checkbox в свойствах статьи на вкладке "Identity Range", который фактически разрешает ручное управление диапазоном identity [Рис. 1.2].

Рис. 1.2
[Рис. 1.2]

Затем перенесите таблицу на подписчика. Вы можете использовать DTS, резервное копирование/восстановление, BCP, прилинкованные сервера - в зависимости оттого, что Вы предпочитаете. Таблица может быть передана, как только у неё будет столбец uniqueidentifier, с установленным свойством rowguid, в противном случае при синхронизации Вы получите ошибку, приведенную ниже:

Error: Invalid column name 'rowguidcol'.

Пока с публикуемой статьёй всё нормально, эта ошибка не может проявиться, поскольку таблица уже имеет столбец rowguid или публикация этой таблицы добавит его к таблице.
Затем, на подписчике повторно устанавливают текущее и начальное значение identity. Почему это необходимо? Рассмотрим случай, когда есть 4 записи:

ID

Company

rowguid

1

HP

{5B9D38B2-5089-4C42-816B-48D0157ADA34}

2

DH

{5A17C1B2-C045-4279-87BE-38F5F4959C0B}

3

IBM

{B2FF82DA-5384-42AF-92F0-4029A5908395}

4

Microsoft

{AB637574-7EBF-4950-9865-5378166BEB96}

Если издатель имеет начальное значение (seed) = 2 и приращение (increment) = 2, а первый подписчик имеет начальное значение = 1 и приращение = 2, в обоих случаях, следующая запись будет иметь ID 6. Это потому, что текущее значение identity - 4, таким образом, в обоих случаях, следующее значение будет 4 + 2. Значит, нужно запустить на подписчике:

DBCC CHECKIDENT (tCompany, RESEED, 5)

чтобы начать правильный отсчет. Это можно сделать, используя скрипт из моментального снимка, после того как он был применён, но начальное значение и приращение должны быть изменены вручную, и мы, в таком случае имеем один дополнительный ручной шаг - это самое легкое решение. Фактически этот шаг может быть сделан вручную, и начальное значение с приращением на подписчике можно оставить такими же, как и на издателе, а так как в этом примере значение identity повышается парами, то будет достаточно переопределения текущего значения identity. Однако это может запутать администратора, так как потом всегда придётся анализировать начальное значение и приращения таблицы, чтобы определить значения устанавливаемых границ.
Наконец выполните инициализацию подписчика без первоначальной синхронизации данных. Если Вы делаете это с помощью скриптов, то воспользуйтесь хранимой процедурой sp_addsubscription с параметром @sync_type=none, или через GUI выбрав опцию, приведенную ниже [Рис. 1.3].

Рис. 1.3
[Рис. 1.3]

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

[В начало]

(2) Использование @creation_script в sp_addmergearticle

Второй метод GUI полностью не поддерживается. Он требует разработки отдельного сценария для создания таблицы на подписчике:

exec sp_addmergearticle @publication = N'TestIdentitiesXXX', 
			@article = N'tCompany', 
			@source_owner = N'dbo',
 			@source_object = N'tCompany', 
			@type = N'table', 
			@description = null, 
			@column_tracking= N'true', 
			@pre_creation_cmd = N'drop', 
			@creation_script = 'C:\misc\tCompany.sql',
			@schema_option = 0x00, 
			@article_resolver = null, 
			@subset_filterclause =null, 
			@vertical_partition = N'false', 
			@destination_owner = N'dbo', 
			@auto_identity_range= N'false', 
			@verify_resolver_signature = 0, 
			@allow_interactive_resolver =N'false', 
			@fast_multicol_updateproc = N'true', 
			@check_permissions = 0

Список аргументов стандартный, за исключением аргумента @creation_script, который определяет файл, используемый при создании таблицы, и аргумента @schema_option, который предписывает использование упомянутого выше файла. Этот скрипт(C:\misc\tCompany.sql), созданный с помощью Enterprise Manager на издателе, просто создаёт скрипт таблицы, но с начальным значением (seed) identity, отличным от издателя:

[ID] [int] IDENTITY (2, 2) NOT FOR REPLICATION NOT NULL

После инициализации текущее значение identity необходимо изменить еще раз, чтобы повторно определить отправную точку.
После того, как будет запущен snapshot agent, текстовый файл скрипта будет передан в repldata share. В этом файле можно будет вручную изменить параметры identity до инициализации подписчиков. Теоретически, такие изменения могут быть сделаны, с помощью системной хранимой процедуры, которая позволяет изменить детали существующей статьи - sp_changemergearticle. Однако, как только один из подписчиков синхронизировался, изменится сценарий создания, использующий этот метод, что лишит законной силы эту подписку, и Вы будете обязаны повторно инициализировать всех остальных подписчиков (@force_invalidate_snapshot = 1 и @force_reinit_subscription = 1). На практике файл может быть изменен только вручную.
Любые другие статьи можно будет добавлять к этой публикации стандартным методом.

Заключение

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

[В начало]

Перевод: Маргариты Баскаковой  2005г.

Rambler's Top100 Рейтинг@Mail.ru  Administrator: Обратная связь 
Copyright: SQL.Ru 2000-2013