加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > MsSql教程 > 正文

SQLServer ucMSrepl_transactions和ucMSrepl_commands插入重复键

发布时间:2020-12-12 13:11:51 所属栏目:MsSql教程 来源:网络整理
导读:起因: 1. 将一个存储过程发布并启用快照时(可更新订阅),分发事务表和命令表插入了重复键导致冲突,程序不断重试。 队列读取器不断报错,同时也导致分发代理出错不能进行分发。错误如下: 错误消息:进程无法在“ServerName”上执行“sp_MSadd_replcmds”


起因:

1. 将一个存储过程发布并启用快照时(可更新订阅),分发事务表和命令表插入了重复键导致冲突,程序不断重试。

队列读取器不断报错,同时也导致分发代理出错不能进行分发。错误如下:

错误消息:
进程无法在“ServerName”上执行“sp_MSadd_replcmds”。 (源: MSSQLServer,错误号: 1007)

不能在具有唯一索引 'ucMSrepl_transactions' 的对象 'dbo.MSrepl_transactions' 中插入重复键的行。重复的键值为 (8,0x0012061a0000190a0052)。
不能在具有唯一索引 'ucMSrepl_commands' 的对象 'dbo.MSrepl_commands' 中插入重复键的行。重复的键值为 (8,0x0012061a0000190a0052,1)。
不能在具有唯一索引 'ucMSrepl_commands' 的对象 'dbo.MSrepl_commands' 中插入重复键的行。重复的键值为 (8,2)。
不能在具有唯一索引 'ucMSrepl_commands' 的对象 'dbo.MSrepl_commands' 中插入重复键的行。重复的键值为 (8,3)。
不能在具有唯一索引 'ucMSrepl_commands' 的对象 'dbo.MSrepl_commands' 中插入重复键的行。重复的键值为 (8,4)。 
(源: MSSQLServer,错误号: 1007)

未将批提交到分发服务器。 (源: MSSQL_REPL,错误号: MSSQL_REPL22020)

The last step did not log any message! (源: MSSQL_REPL,错误号: MSSQL_REPL22037)
(按理存储过程的发布是不会影响到表的,但是这里出现问题了。可能情况是分发表插入因未使用事务保证完整性,遇到某问题导致事务中断停止,然后日志读取器又重新读写到分发表中,导致冲突!)


2. 由于错误一直进行,于是就将该事务和命令从分发表中删除!

DELETE FROM distribution.dbo.MSrepl_commands 
WHERE publisher_database_id=8 AND xact_seqno=0x0012061a0000190a0052

DELETE FROM distribution.dbo.MSrepl_transactions 
WHERE publisher_database_id=8 AND xact_seqno=0x0012061a0000190a0052

删除之后,日志读取器又出现新的问题了!(这个错误是可以模拟重现的,以下的错误信息可能不是在相同的环境了,因为测试过几次不记得保留哪份了!)

错误消息:
进程无法在“ServerName”上执行“sp_repldone/sp_replcounters”。 (源: MSSQL_REPL,错误号: MSSQL_REPL20011)

为 repldone 日志扫描指定的 LSN {00000000:00000000:0000} 出现在日志 {00000217:00000013:000a} 中的当前复制开始之前。 (源: MSSQLServer,错误号: 18768)

进程无法设置上次分发的事务。 (源: MSSQL_REPL,错误号: MSSQL_REPL22017)

进程无法在“ServerName”上执行“sp_repldone/sp_replcounters”。 (源: MSSQL_REPL,错误号: MSSQL_REPL22037)

这导致了扫描日志的序列号不连续了!~


没办法,最终将所有事务标识为已分发跳过了!因为本人环境允许,使用的是可更新订阅,用户都在订阅库操作,所以分发的数据是没什么用的,但是系统还是要判断。

最终解决办法:

exec sp_repldone @xactid = NULL,@xact_segno = NULL,@numtrans = 0,@time = 0,@reset = 1

exec sp_replflush 

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读