Ошибка репликации SQL "строка не найдена" - PullRequest
10 голосов
/ 20 февраля 2009

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

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

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

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

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

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

Но как мне найти таблицу и строку из этого? Есть идеи?

Ответы [ 8 ]

11 голосов
/ 21 апреля 2010

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

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'
9 голосов
/ 20 февраля 2009

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

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

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

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

3 голосов
/ 20 февраля 2009

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

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

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

1 голос
/ 01 августа 2012

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

USE [distribution]

select * from dbo . MSarticles 
where article_id IN ( SELECT Article_id from MSrepl_commands 
where xact_seqno = 0x0003BB0E000001DF000600000000)
0 голосов
/ 25 декабря 2016

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

Поскольку эта запись не существует на подписчике, репликация выдает ошибку «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

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

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

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

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

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

0 голосов
/ 24 апреля 2014

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

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

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

0 голосов
/ 08 июля 2009
Конечно,

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

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

Трис

...