SQL 复制“未找到行” 错误

发布于 2024-07-13 20:39:08 字数 388 浏览 6 评论 0原文

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

SQL Server 给我这条消息:

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

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

目前我找到的最详细的数据是:

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

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

I have transactional replication running between two databases. I fear they have fallen slightly out of sync, but I don't know which records are affected. If I knew, I could fix it manually on the subscriber side.

SQL Server is giving me this message:

The row was not found at the Subscriber when applying the replicated command. (Source: MSSQLServer, Error number: 20598)

I've looked around to try to find out what table, or even better what record is causing the issue, but I can't find that information anywhere.

The most detailed data I've found so far is:

Transaction sequence number: 0x0003BB0E000001DF000600000000, Command ID: 1

But how do I find the table and row from that? Any ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

苏佲洛 2024-07-20 20:39:09

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

USE [distribution]

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

Use this query to find out the article that is out of sync:

USE [distribution]

select * from dbo . MSarticles 
where article_id IN ( SELECT Article_id from MSrepl_commands 
where xact_seqno = 0x0003BB0E000001DF000600000000)
萌酱 2024-07-20 20:39:09

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

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

特里斯

of course if you check the error when the replication fails it also tells you which record is at fault and you could extract that data from the core system and just insert it on the subscriber.

This is better than skipping errors as with the SQL Data Compare it will lock the table for the comparison and if you have millions of rows this can take a long time to run.

Tris

一腔孤↑勇 2024-07-20 20:39:09

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

Changing the profile to "Continue on data consistency errors" won't always work. Obviously it reduces or nullifies an error, but you won't get the whole proper data. It will skip the rows by which an error occurs, and hence you fail to get accurate data.

素年丶 2024-07-20 20:39:09

以下检查解决了我的问题,

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

the following checks resolve my problem

  • 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
  • after a very short time all data in subscription were updated and no
    other error in replication monitor
  • in my case all above queries did not returned nothing
夜未央樱花落 2024-07-20 20:39:09

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

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

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

我们可以使用以下查询检查发布者的请求是否是更新或删除语句:

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. 如果是更新语句:

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

This error usually comes when particular record does not exists on subscriber and a update or delete command executed for same record on primary server and which got replicated on subscriber as well.

As this records does not exists on subscriber, replication throws an error " Row Not Found"

Solution of this error to make replication work back to the normal running state:

We can check with following query, whether request at publisher was of update or delete statement:

USE [distribution]

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

We can get artical id information from above query, which can be passed to below proc:

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

Above query will give information about, whether it was a update statement or delete statement.

  1. In Case of Delete Statement

That record can be directly deleted from msrepl_commands objects so that replication wont make retry attempts for the record

DELETE FROM msrepl_commands
WHERE  publisher_database_id = 1
       AND command_id =1
       AND xact_seqno = 0x00099979000038D6000100000000 
  1. In case of update statement:

You need to insert that record manually from publisher DB to subscriber DB:

酒解孤独 2024-07-20 20:39:08

这将为您提供错误所在的表

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'

This gives you the table the error is against

use distribution
go

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

And this will give you the command (and the primary key (ie the row) the command was executing against)

exec sp_browsereplcmds 
@xact_seqno_start = '0x0003BB0E000001DF000600000000', 
@xact_seqno_end = '0x0003BB0E000001DF000600000000'
葬花如无物 2024-07-20 20:39:08

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

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

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

请记住,要实现此目的,您的发布数据库需要在比较和修复订户数据库的过程中保持“安静”。 幸运的是,在这种情况下我有这种奢侈。

I'll answer my own question with a workaround I ended up using.

Unfortunately, I could not figure out which table was causing the issue through the SQL Server replication interface (or the Event Log for that matter). It just didn't say.

So the next thing I thought of was, "What if I could get replication to continue even though there is an error?" And lo and behold, there is a way. In fact, it's easy. There is a special Distribution Agent profile called "Continue on data consistency errors." If you enable that, then these types of errors will just be logged and passed on by. Once it is through applying the transactions and potentially logging the errors (I only encountered two), then you can go back and use RedGate SQL Data Compare (or some other tool) to compare your two databases, make any corrections to the subscriber and then start replication running again.

Keep in mind, for this to work, your publication database will need to be "quiet" during the part of the process where you diff and fix the subscriber database. Luckily, I had that luxury in this case.

装迷糊 2024-07-20 20:39:08

如果您的数据库不是太大,我会停止复制,重新创建快照,然后重新启动复制。 此technet 文章介绍了这些步骤。

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

这篇复制文章值得一读。

If your database is not prohibitively large, I would stop replication, re-snapshot and then re-start replication. This technet article describes the steps.

If it got out of sync due to a user accidently changing data on the replica, I would set the necessary permissions to prevent this.

This replication article is worth reading.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文