ITPub博客

首页 > Linux操作系统 > Linux操作系统 > 合并复制无法使用Management Studio查看和解决冲突

合并复制无法使用Management Studio查看和解决冲突

原创 Linux操作系统 作者:apgcdsd 时间:2011-08-16 08:05:50 0 删除 编辑
Normal 0 7.8 pt 0 2 false false false EN-US ZH-CN X-NONE合并复制无法使用Management Studio查看和解决冲突

SQL Server中,我们提供了复制的功能以便多个SQL Server的实例能够共享数据。在复制的家族中,我们又提供了多种的选择。其中,如果多个SQL Server的实例需要共享修改时,我们需要使用合并复制。由于多个SQL Server实例能够修改相同的数据,导致数据修改的冲突,即不同的SQL Server实例修改在同步之前修改了相同的数据。在合并复制中,我们提供的一套完善的方法用来解决这个冲突问题。在自动的冲突检测和处理机制之后,冲突可以被用户手动根据需要查看和修改。

 


但是,在查看冲突的时候,用户可能会遇到如下的错误。

 


 一般情况下,遇到这种错误要去解决是比较困难的。甚至需要检查Management Studio这个菜单的相关源码。但是,从这个错误本身来看,它是由于无法找到一个叫rowguid的列导致的。

对于这种错误,我们首先可以使用事件查探器(Profiler Trace)来查看是否有是Management StudioView Conflicts中运行的语句产生的错误。我们可以使用时间查探器的列筛选功能使其只抓取Management Studio的语句。



当我们选择View Conflicts菜单项的时候,以上错误窗口就会被弹出。在点击Ok按钮后,相应的冲突查看窗口就会被显示。在事件查探器中,我们没有发现任何误。在错误报告之前,如下的语句会被执行。(其中,test是出现冲突的表名)

sp_helpmergeconflictrows

sp_helpmergedeleteconflictrows

select *from [dbo].[test] where 1=2

select *, type_name(xtype) as datatype, (status & 0x80) as identitystatus from syscolumns where id = object_id('[dbo].[test]')

由此我们知道,这个错误并不是由于语句报错导致的。而是由于返回给Management Studio的相关结果集有一定的问题。即合并复制系统表中的数据存在一定的问题。

以下就是比较笨的方法了。我们将每个语句抓取出来,并再次在环境中运行。如果有运行良好的环境,我们可以将结果作一定的对比。这样能够迅速定位出现问题的语句。例如,在运行良好和有问题的环境中运行了sp_helpmergeconflictrows存储过程之后,我们发现问题环境返回的列少。而且,没有返回rowguid列。我们之后在合并复制中rowguid列被用来唯一标记一条数据。如果rowguid没有被返回,之后的一系列系统数据都可能不能被返回。

正常结果:


有问题结果:


我们之后可以使用sp_helptext查看sp_helpmergeconflictrows的内容。经过分析,我们知道这个存储过程会将冲突表(MSmerge_conflict_Test.Publicatication_test)MSmerge_conflict_info做链接,并且返回相关的数据。具体语句如下,

select @colid = min(column_id) from sys.columns

where object_id = object_id(@conflict_table)

 select @colname=name from sys.columns

where object_id = object_id(@conflict_table) and column_id=@colid

 select @cmd = 'select '

 while (@colname is not NULL)

 begin

  if @colname <> 'origin_datasource_id'

  begin

   select @quotedcolname = quotename(@colname)

   select @cmd = @cmd + ' ct.' + @quotedcolname + ','

  end

  select @colid = min(column_id) from sys.columns

where object_id = object_id(@conflict_table) and column_id > @colid

  select @colname = NULL

  select @colname=name from sys.columns

where object_id = object_id(@conflict_table) and column_id=@colid

 end

    select @cmd = @cmd + ' m.origin_datasource, m.conflict_type, m.reason_code, m.reason_text, m.pubid, m.MSrepl_create_time from'

    select @cmd = @cmd + QUOTENAME(@conflict_table) + ' ct, MSmerge_conflicts_info m where ct.origin_datasource_id=m.origin_datasource_id

       and m.conflict_type<>4 and ct.rowguidcol=m.rowguid '

 

当我们将@conflict_table参数带入上段代码时,我们发现第一条语句就没有能够返回任何数据。经过思考,我们可以非常自信的得出结论。

select min(column_id) from sys.columns

where object_id = object_id('MSmerge_conflict_Test.Publicatication_test')

冲突表的命名机制为MSmerge_conflict__

。所以,我们可以得到这个有问题的环境中,发布的名字为Test.Publication。当创建和使用这个环境时,都不会有任何问题。但是,如果对这个要查看这个发布的冲突时,object_id()函数会将点(.)当作架构名(Schema Name)和表名(Table Name)之间的分隔符。所以,object_id()找不到一个架构名是Test并且表名是Publication的表,最后这个函数会返回NULL。从而导致rowguid列不能被返回及我们观察到的错误。

最后,我们的结论是,在合并复制中,不能在发布名中使用点(.)。否则会导致冲突查看功能不可用。总结我们在这个这种问题中的经验,我们可以将这种问题的解决步骤总结为,

1.       分析错误的可能原因

2.       抓取事件查探器日志,检查是否有语句报错。

3.       如果没有语句报错,逐条检查语句返回的结果是否有异常。

4.       如果发现返回结果异常,查看是否可以找出异常原因。

当然,如果这一切都还不能揭开迷雾。我们CSS数据库部门是您最好的选择。

12_1.jpg

12_2.jpg

12_3.jpg

12_4.jpg

12_5.jpg

12_6.jpg

12_7.jpg

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/25175503/viewspace-704949/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论