Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Помогите разобраться с репликацией.  [new]
gang
Member

Откуда:
Сообщений: 1394
Коллеги помогите разобраться с такой ситуацией:
SQL2008R2EEx64(SP1)
Есть репликация транзакциями с обновляемыми подписчиками. Реплицируемые данные фильтруются по флагу
отправки на подписчика и по имени подписчика. Реплицируемая таблица большая (~10ков Гб).
Разработчики время от времени добавляют сущностям новые свойства - столбцы таблицы.
С добавлением проблем нет (is null, констрейнты сразу не вешаются). Но потом необходимо проапдейтить
новое поле к-либо значениями. Соответственно все это идет долго, приходится делать кусками чтобы не
заткнулся логридер и т.п. Читал, что можно выполнять подобные задачи через репликацию процедур. (например тут)
Попробовал настроить в тестовой среде и получил следующую неприятную ошибку: после того как реплицируемые
строки апдейтятся через процедуру (изменения отображаются на подписчике) изменения через прямой апдейт
перестают передаваться на подписчика, а при попытке выполнить update на стороне подписчика выдается ошибка

Msg 20515, Level 16, State 1, Procedure sp_MSreplraiserror, Line 9
Updateable Subscriptions: Rows do not match between Publisher and Subscriber. Run the Distribution Agent to refresh rows at the Subscriber.


Причем это относится только к строкам затронутым апдейтом из процедуры. Строки не отправленные на подписчика
на момент запуска проц-ры в дальнейшем успешно реплицируются в обоих направлениях.
Вот тут написано, что использование фильтров в статье приводит к тому что данные считаются
non-convergent (in other words the data does not match)

Вот и возникают вопросы:
-Кто-нибудь сталкивался с подобным поведением?
-Т.к. с репликами работал не очень плотно не могу понять это фича или бага?
-Можно ли вообще в моем сценарии использовать проц-ры для ускорения административных манипуляций?
-Нет ли к-либо опций в настройках реплик\статей позволяющих избежать данного поведения?

Скрипт для воспроизведения в аттаче.

К сообщению приложен файл (update with sp.sql - 10Kb) cкачать
11 июл 12, 12:20    [12849733]     Ответить | Цитировать Сообщить модератору
 Re: Помогите разобраться с репликацией.  [new]
invm
Member

Откуда: Москва
Сообщений: 9405
У вас опубликована и таблица и процедура, изменяющая данные в этой таблице. В результате один update на издателе приводит к двум update на подписчике.
11 июл 12, 12:46    [12849978]     Ответить | Цитировать Сообщить модератору
 Re: Помогите разобраться с репликацией.  [new]
gang
Member

Откуда:
Сообщений: 1394
Насколько я понимаю как раз нет. Смысл публикации проц-ры в том чтобы реплицировалась только команда запуска проц-ры.
По данным ReplicationMonitor-a именно так и получается. При запуске проц-ры:
Картинка с другого сайта.
При прямом апдейте:
Картинка с другого сайта.
Или я где-то ошибаюсь?
11 июл 12, 13:33    [12850378]     Ответить | Цитировать Сообщить модератору
 Re: Помогите разобраться с репликацией.  [new]
invm
Member

Откуда: Москва
Сообщений: 9405
gang,

Вы правы, репликация значительно поумнела и реплицируется только вызов процедуры. Вот в этом и есть проблема.
Как оно работает:

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

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

Лечится достаточно просто, процедура на издателе и подписчиках должна выглядеть примерно так:
alter proc dbo.my_admin_proc
 (@idmax int= null)
as 
begin

select @idmax=ISNULL(@idmax, 999999);

declare @msrepl_tran_version uniqueidentifier;

select
 @msrepl_tran_version = 0x0000000000000000;
                         
update replicated_table
 set
  value=value+1,
  msrepl_tran_version = case when pole = 'replicate' then @msrepl_tran_version else msrepl_tran_version end
where
 id<=@idmax;

end;
11 июл 12, 19:11    [12852802]     Ответить | Цитировать Сообщить модератору
 Re: Помогите разобраться с репликацией.  [new]
gang
Member

Откуда:
Сообщений: 1394
invm, спасибо большое. Тоже заметил, что msrepl_tran_version разъезжаются, но думал может есть встроенное "не ручное" решение.
А Вы такими проц-ми пользуетесь? меня немного насторожил вот этот момент:
select 
 @msrepl_tran_version = 0x0000000000000000;

Получается что при апдейте проц-й реплицируемых строк msrepl_tran_version у них обнуляется.
Может лучше писать что-то определенное, например так:
create proc [dbo].[my_admin_proc] (@idmax int= null,@msrepl_tran_version uniqueidentifier ) as 
begin
select @idmax=ISNULL(@idmax, 999999);
update replicated_table
 set
  value=value+1,
  msrepl_tran_version = case when pole = 'replicate' then @msrepl_tran_version else msrepl_tran_version end
where
 id<=@idmax;
end;
GO
--Вызов
declare @msrepl_tran_version uniqueidentifier 
select @msrepl_tran_version=newid() 
exec ReplicaMain..my_admin_proc null, @msrepl_tran_version

Еще раз большое спасибо.
12 июл 12, 10:55    [12854802]     Ответить | Цитировать Сообщить модератору
 Re: Помогите разобраться с репликацией.  [new]
invm
Member

Откуда: Москва
Сообщений: 9405
gang,

Нет, у меня на продакшене нет репликации такого типа. А в msrepl_tran_version может быть любое значение, главное, чтобы оно было одинаковое на издателе и подписчиках.
12 июл 12, 11:16    [12854981]     Ответить | Цитировать Сообщить модератору
 Re: Помогите разобраться с репликацией.  [new]
gang
Member

Откуда:
Сообщений: 1394
invm, ОК спасибо. Допилил тестовый стенд до желаемого результата. Кому интересно скрипт в аттаче. При случае попробую на бою.

К сообщению приложен файл (Working update with sp as isolated article.sql - 15Kb) cкачать
12 июл 12, 12:26    [12855756]     Ответить | Цитировать Сообщить модератору
 Re: Помогите разобраться с репликацией.  [new]
invm
Member

Откуда: Москва
Сообщений: 9405
gang,

А вообще, если есть возможность заменить транзакционную репликацию с обновляемой подпиской на какую-нибудь другую, то рассмотрите этот вариант. Посмотрите триггера на опубликованных таблицах на подписчике -- поймете почему.
12 июл 12, 12:47    [12855975]     Ответить | Цитировать Сообщить модератору
 Re: Помогите разобраться с репликацией.  [new]
gang
Member

Откуда:
Сообщений: 1394
invm, Да, тригера конечно монструозные, но вариантов других нет. Данные едут на подписчиков только на время, причем частично, после чего возвращаются модифицированными. Кроме того в течении времени жизни на подписчике они должны быть "автономны". Так что других вариантов при заданной логике и архитектуре ПО и не остается. Еще раз спасибо за помощь.
13 июл 12, 11:11    [12861663]     Ответить | Цитировать Сообщить модератору
 Re: Помогите разобраться с репликацией.  [new]
invm
Member

Откуда: Москва
Сообщений: 9405
gang, другие варианты есть почти всегда.
С помощью SB или Транзакционной репликации вызовов процедур Издатель->Подписчик и Подписчик->Издатель, можно реализовать практически любую логику обработки.
13 июл 12, 11:22    [12861751]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить