Ошибка репликации SQL: ошибка "Row Not Found"

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

SQL Server сообщает мне следующее сообщение:

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

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

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

Номер последовательности транзакций: 0x0003BB0E000001DF000600000000, Идентификатор команды: 1

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

Ответ 1

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

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'

Ответ 2

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

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

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

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

Ответ 3

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

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

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

Ответ 4

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

USE [distribution]

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

Ответ 5

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

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

трис

Ответ 6

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

Ответ 7

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

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

Ответ 8

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

Поскольку эти записи не существуют на подписчике, репликация вызывает ошибку "Row Not Found"

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

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

USE [distribution]

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

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

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

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

  • В случае удаления заявления

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

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

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