10

我在两个数据库之间运行事务复制。我担心它们会稍微不同步,但我不知道哪些记录受到影响。如果我知道,我可以在订户端手动修复它。

SQL Server 给我这个消息:

应用复制命令时,在订阅服务器上未找到该行。(来源:MSSQLServer,错误号:20598)

我环顾四周,试图找出是什么表,甚至更好的是是什么记录导致了问题,但我在任何地方都找不到该信息。

到目前为止,我发现的最详细的数据是:

交易序号:0x0003BB0E000001DF000600000000,命令ID:1

但是我如何从中找到表格和行?有任何想法吗?

4

8 回答 8

11

这为您提供了错误所针对的表

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'
于 2010-04-21T05:15:37.330 回答
9

我将用我最终使用的解决方法来回答我自己的问题。

不幸的是,我无法通过 SQL Server 复制接口(或事件日志)找出导致问题的表。只是没说。

所以接下来我想到的是,“即使出现错误,如果我可以继续复制会怎样?” 你瞧,有办法。事实上,这很容易。有一个特殊的分发代理配置文件称为“数据一致性错误继续”。如果您启用它,那么这些类型的错误将被记录并传递。一旦通过应用事务并可能记录错误(我只遇到两个),那么您可以返回并使用 RedGate SQL 数据比较(或其他一些工具)来比较您的两个数据库,对订阅者进行任何更正,然后再次开始复制运行。

请记住,要使其正常工作,您的发布数据库需要在您区分和修复订阅者数据库的部分过程中保持“安静”。幸运的是,在这种情况下,我拥有了这种奢侈。

于 2009-02-20T04:51:22.163 回答
3

如果您的数据库不是太大,我会停止复制,重新创建快照,然后重新开始复制​​。这篇technet 文章描述了这些步骤。

如果由于用户意外更改副本上的数据而导致不同步,我将设置必要的权限以防止这种情况发生。

这篇复制文章值得一读。

于 2009-02-19T22:50:07.803 回答
1

使用此查询找出不同步的文章:

USE [distribution]

select * from dbo . MSarticles 
where article_id IN ( SELECT Article_id from MSrepl_commands 
where xact_seqno = 0x0003BB0E000001DF000600000000)
于 2012-07-31T20:13:12.743 回答
0

当然,如果您在复制失败时检查错误,它还会告诉您哪条记录有问题,您可以从核心系统中提取该数据并将其插入订阅者。

这比使用 SQL 数据比较跳过错误要好,它会锁定表以进行比较,如果您有数百万行,这可能需要很长时间才能运行。

特里斯

于 2009-07-08T03:51:07.563 回答
0

将配置文件更改为“继续处理数据一致性错误”并不总是有效。显然,它减少或消除了错误,但您不会获得完整的正确数据。它将跳过发生错误的行,因此您无法获得准确的数据。

于 2010-01-25T14:07:25.770 回答
0

以下检查解决了我的问题

  • 检查所有复制 SQL 代理作业是否正常工作,如果没有启动它们。
    • 在我的情况下,由于阻塞问题,一些 DBA 在几个小时前发生了一些终止会话,因此它被停止了
  • 在很短的时间后,订阅中的所有数据都已更新,并且复制监视器中没有其他错误
  • 在我的情况下,上述所有查询都没有返回任何内容
于 2014-04-24T19:13:53.813 回答
0

当订阅者上不存在特定记录并且在主服务器上为同一记录执行更新或删除命令并且在订阅者上也被复制时,通常会出现此错误。

由于订阅者上不存在此记录,因此复制会引发错误“未找到行”

此错误的解决方法使复制工作恢复到正常运行状态:

我们可以通过以下查询检查发布者的请求是更新还是删除语句:

USE [distribution]

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

我们可以从上面的查询中得到 artical id 信息,这些信息可以传递给下面的 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. 如果是更新声明:

您需要将该记录从发布者数据库手动插入到订阅者数据库:

于 2016-12-25T06:44:21.767 回答