Ошибка строки репликации SQL не найдена

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

SQL Server дает мне это сообщение:

Строка не была найдена на подписчике при применении реплицированной команды. (Источник: MSSQLServer, номер ошибки: 20598)

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

Наиболее подробные данные, которые я нашел до сих пор, это:

Порядковый номер транзакции: 0x0003BB0E000001DF000600000000, идентификатор команды: 1

Но как мне найти таблицу и строку из нее? Любые идеи?


person jeremcc    schedule 19.02.2009    source источник


Ответы (8)


Это дает вам таблицу, против которой ошибка

use distribution
go

select * from dbo.MSarticles
where article_id in (
    select article_id from MSrepl_commands
    where xact_seqno = 0x0003BB0E000001DF000600000000)

И это даст вам команду (и первичный ключ (то есть строку), против которой выполнялась команда)

exec sp_browsereplcmds 
@xact_seqno_start = '0x0003BB0E000001DF000600000000', 
@xact_seqno_end = '0x0003BB0E000001DF000600000000'
person Matthew    schedule 21.04.2010

Я отвечу на свой вопрос обходным путем, который я использовал.

К сожалению, я не смог выяснить, какая таблица вызывала проблему через интерфейс репликации SQL Server (или, если на то пошло, журнал событий). Просто не сказал.

Итак, следующее, о чем я подумал, было: «А что, если бы я мог продолжить репликацию даже при наличии ошибки?» И вот, есть способ. На самом деле, это легко. Существует специальный профиль агента распространителя, который называется «Продолжать при ошибках согласованности данных». Если вы включите это, то эти типы ошибок будут просто регистрироваться и передаваться. После применения транзакций и, возможно, регистрации ошибок (я столкнулся только с двумя), вы можете вернуться и использовать RedGate SQL Data Compare (или какой-либо другой инструмент), чтобы сравнить две ваши базы данных, внести любые исправления в подписчика, а затем снова запустить репликацию.

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

person jeremcc    schedule 20.02.2009
comment
Для этого через SSMS щелкните правой кнопкой мыши Репликация -> Свойства распространителя. Затем нажмите «Профиль по умолчанию». Вы можете создать новый профиль со значением -SkipErrors. Или просто установите флажок Продолжить при ошибках согласованности данных. и выберите Изменить существующих агентов. - person Trevor; 21.12.2013

Если ваша база данных не слишком велика, я бы остановил репликацию, повторно сделал снимок, а затем снова начал репликацию. Эта статья technet описывает шаги.

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

Эту статью о репликации стоит прочитать.

person Mitch Wheat    schedule 19.02.2009
comment
Да, я пытаюсь этого избежать, так как столы очень большие. Посмотрим, придется ли мне в конечном итоге идти туда. - person jeremcc; 20.02.2009
comment
У вас есть инструмент сравнения данных RedGate? (у него 14-дневная пробная версия) Это, по крайней мере, позволит вам быстро найти строки. - person Mitch Wheat; 20.02.2009
comment
Ага, именно этим я и пользуюсь. :-) Проблема в том, что текущий diff говорит мне, что x строк отсутствует (поскольку репликация отстает), но я не знаю, какая из них виновата. Я думаю, что нашел обходной путь, хотя. Это связано с флагом SkipErrors на дистрибьюторе. Я опубликую это в ближайшее время. - person jeremcc; 20.02.2009

Используйте этот запрос, чтобы найти статью, которая не синхронизирована:

USE [distribution]

select * from dbo . MSarticles 
where article_id IN ( SELECT Article_id from MSrepl_commands 
where xact_seqno = 0x0003BB0E000001DF000600000000)
person KShan    schedule 31.07.2012

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

Это лучше, чем пропускать ошибки, так как при сравнении данных SQL блокируется таблица для сравнения, и если у вас есть миллионы строк, это может занять много времени.

Трис

person Community    schedule 08.07.2009

Изменение профиля на «Продолжать при ошибках согласованности данных» не всегда будет работать. Очевидно, что это уменьшает или сводит на нет ошибку, но вы не получите всех правильных данных. Он пропустит строки, в которых возникает ошибка, и, следовательно, вы не сможете получить точные данные.

person Shahid    schedule 25.01.2010

следующие проверки решают мою проблему

  • check that all the replication SQL Agents jobs are working fine and if not start them.
    • in my case it was stopped because of some killed session occurred a few hours before by Some DBA because of blocking issue
  • через очень короткое время все данные в подписке были обновлены, и никаких других ошибок в мониторе репликации не было.
  • в моем случае все вышеуказанные запросы ничего не вернули
person Iman    schedule 24.04.2014

Эта ошибка обычно возникает, когда конкретная запись не существует на подписчике, а команда обновления или удаления выполняется для той же записи на основном сервере, которая также реплицируется на подписчике.

Поскольку таких записей на подписчике не существует, репликация выдает ошибку «Строка не найдена».

Решение этой ошибки, чтобы вернуть репликацию в нормальное рабочее состояние:

Мы можем проверить с помощью следующего запроса, был ли запрос у издателя оператором обновления или удаления:

USE [distribution]

SELECT *
FROM   msrepl_commands 
WHERE  publisher_database_id = 1
       AND command_id = 1
       AND xact_seqno = 0x00099979000038D6000100000000

Мы можем получить информацию об искусственном идентификаторе из приведенного выше запроса, который можно передать нижеприведенной процедуре:

EXEC Sp_browsereplcmds
  @article_id = 813,
  @command_id = 1,
  @xact_seqno_start = '0x00099979000038D60001',
  @xact_seqno_end = '0x00099979000038D60001',
  @publisher_database_id = 1

Приведенный выше запрос предоставит информацию о том, был ли это оператор обновления или оператор удаления.

  1. В случае заявления об удалении

Эта запись может быть удалена напрямую из объектов msrepl_commands, чтобы репликация не предпринимала повторных попыток для записи.

DELETE FROM msrepl_commands
WHERE  publisher_database_id = 1
       AND command_id =1
       AND xact_seqno = 0x00099979000038D6000100000000 
  1. В случае заявления об обновлении:

Вам нужно вручную вставить эту запись из БД издателя в БД подписчика:

person Sanjay Aswani    schedule 25.12.2016