对等复制中的冲突检测

日期

2014-12-04

 

 

分类

Sqlserver高可用性

小类

对等复制

实验环境

windows 2008R2 SqlServer2014

功能点

对等复制中的冲突检测

错误信息

在事务 ID 为 0x000000000000db32 的对等方 2 (传入)和事务 ID 为 0x000000000000190f 的对等方 100 (在磁盘上)之间的对等方 100 处检测到类型为 'Update-Update' 的冲突

if @@trancount > 0 rollback tran

 

 

 

1. 通过复制监视器查看详细信息

显示“执行一批命令时出错。正在重试单个命令。”,界面如1.1:

 

gem 执行任何命令 没反应 执行命令时出错_冲突检测

 

2. 查看sqlserver2014的日志

发现对等复制错误信息“A conflict of type 'Update-Update' was detected at peer (null) between peer 100 (incoming), transaction id 0x000000000000190d  and peer 2 (on disk), transaction id 0x000000000000db32”,具体界面如1.2:

 

 

gem 执行任何命令 没反应 执行命令时出错_同步错误排查_02

 

3. 查询sqlserver本地帮助

提供 sp_helpsubscriptionerrors 存储过程,查看复制订阅的错误信息。sp_helpsubscriptionerrors 存储过程参数如下:

sp_helpsubscriptionerrors [ @publisher = ] 'publisher'
        , [ @publisher_db = ] 'publisher_db' 
        , [ @publication = ] 'publication' 
        , [ @subscriber = ] 'subscriber' 
        , [ @subscriber_db = ] 'subscriber_db'

 

通过存储过程发现,对等复制的详细错误如下1.3:

 

gem 执行任何命令 没反应 执行命令时出错_SQL Server_03

 

4. 通过步骤发现表中记录的 xact_seqno 事务序列号。

xact_seqno,Specifies the lowest valued exact sequence number to return. xact_seqno_start is nchar(22), with a default of 0x00000000000000000000. 

有了 xact_seqno我们可以通过[distribution]系统库,获取该命令的更详细的信息包含(执行的同步命令),与之相关的系统表[distribution].dbo.MSrepl_commands如下

 

MSrepl_commands 表包含复制的命令行数。 

该表存储在分发数据库中。

列名

数据类型

说明

publisher_database_id

int

发布服务器数据库的 ID。

xact_seqno

varbinary(16)

事务序列号。

类型

int

命令类型。

article_id

int

项目的 ID。

originator_id

int

发起方的 ID。

command_id

int

命令的 ID。

partial_command

bit

指示这是否为部分命令。

command

varbinary(1024)

命令值。

hashkey

int

仅供内部使用。

originator_lsn

varbinary(16)

标识原始发布中命令的 LSN。

这在对等事务复制中使用。

 

 

5. 解析xact_seqno 事务序列号对应的同步命令。

有了 xact_seqno,我们可以通过相关的系统存储过程解析对应的同步命令,相关的存储名[distribution].dbo.sp_browsereplcmds

sp_browsereplcmds [ [ @xact_seqno_start = ] 'xact_seqno_start' ]
    [ , [ @xact_seqno_end = ] 'xact_seqno_end' ] 
    [ , [ @originator_id = ] 'originator_id' ]
    [ , [ @publisher_database_id = ] 'publisher_database_id' ]
    [ , [ @article_id = ] 'article_id' ]
    [ , [ @command_id= ] command_id ]
    [ , [ @agent_id = ] agent_id ]
    [ , [ @compatibility_level = ] compatibility_level ]

        

简单的语法如下1.4:

exec distribution.dbo.sp_browsereplcmds '0x0000002D000037C4000A00000000','0x0000002D000037C4000A00000000'

 

gem 执行任何命令 没反应 执行命令时出错_SQL Server_04

取出命令即可发现同步错误命令。

 

第二部分 对等复制冲突的解决办法

 

查看在线帮助文档:http://msdn.microsoft.com/zh-cn/library/bb934199.aspx

 

 

在对等复制之类的系统中,在单个对等节点上提交更改之后将检测不到冲突。相反,在复制这些更改并将其应用于其他对等节点之后,才能够检测到这些更改。在对等复制中,用来将更改应用于每个节点的存储过程会基于每个已发布表中的某个隐藏列来检测冲突。该隐藏列所存储的 ID 将您为每个节点指定的“发起方 ID”与行版本结合起来。在同步期间,分发代理会针对每个表执行同步过程。这些过程会应用来自其他对等节点的插入、更新和删除操作。如果某个过程在读取该隐藏列的值时检测到冲突,将会引发严重级别为 16 的错误 22815:

 

在事务 ID 为 %s 的对等方 %d (传入)和事务 ID 为 %s 的对等方 %d (在磁盘上)之间的对等方 %d 处检测到类型为 '%s' 的冲突。

·  插入-插入 

·  每个表中所有参与对等复制的行都使用主键值进行唯一标识。 在将具有相同键值的行插入到多个节点时,会发生插入-插入冲突。 

·  ·  更新-更新 

·  在多个节点上更新了同一行时发生。 

·  ·  插入-更新 

·  在以下情况下发生:在一个节点上更新了某行,但是在另一个节点上删除了该行,然后又重新插入该行。 

·  ·  插入-删除 

·  在以下情况下发生:在一个节点上删除了某行,但是在另一个节点上删除了该行,然后又重新插入该行。 

·  ·  更新-删除 

·  在以下情况下发生:在一个节点上更新了某行,但是在另一个节点上删除了该行。 

·  ·  删除-删除 

·  在多个节点上删除了同一行时发生。 

解决办法,在线文档写的很明白,这里提供另一个解决办法

 

 

1. 通过以上介绍我们可以发现该错误的错误号“22815”。2. 设置代理配置文件,跳过该错误,继续同步数据。会导致数据不一致1.5。

 

gem 执行任何命令 没反应 执行命令时出错_对等复制_05

 

3. 通过错误命令解析,手动修补数据。