zoukankan      html  css  js  c++  java
  • 复制中数据冲突解决

    在复制中,有的时候会出现订阅端被人修改,导致发布端插入数据的时候主键冲突,这个时候我们要做的不是直接的初始化太过暴力,而对于生产环境来说,这样的操作代价也会很大。下面会说几种方法来处理冲突:

    1、  查看出错的复制命令的具体内容

    如果在复制监视器的订阅详细信息中查看分发代理出错信息时,如果发错发生在应用复制命令时,则可以看到类似信息:
    尝试的命令:

            If @@TRANCOUNT > 0 rollback tran

           (事务序列号:.......)

        错误消息:

    违反了primary key 约束'%s'。不能在对象'%S'中插入重复键.

    如下例子:

    尝试的命令:
    if @@trancount > 0 rollback tran
    (事务序列号: 0x0001D2A8000005D4002700000000,命令 ID: 2)
    
    错误消息:
    Violation of PRIMARY KEY constraint 'PK_SOMasterExtention'. Cannot insert duplicate key in object 'dbo.SOMasterExtention'. The duplicate key value is (600001). (源: MSSQLServer,错误号: 2627)
    获取帮助: http://help/2627
    Violation of PRIMARY KEY constraint 'PK_SOMasterExtention'. Cannot insert duplicate key in object 'dbo.SOMasterExtention'. The duplicate key value is (600001). (源: MSSQLServer,错误号: 2627)
    获取帮助: http://help/2627

    在上面我们可以看到事务的序列号为 : 0x0001D2A8000005D4002700000000   ,而冲突主键为: 600001  ,但有的时候这个主键会不准确,当多个的时候也只是会显示插入的第一个主键。

    我们可以通过以下语句来看一下有多少的事务

    use distribution
    go
    sp_browsereplcmds '0x0001D2A8000005D4002700000000' ,'0x0001D2A8000005D4002700000000'

    可以看到以下结果:

    由上面可以看到是8条插入语句在发布库执行。command 默认的命名规则是sp_MS+operation+schemaName+tableName ,可以通过下面这个查询定位到具体表

    DECLARE @article_id int 
    SET @article_id = 3
    USE distribution
    GO 
    SELECT * FROM  MSarticles WHERE article_id=@article_id 

    可以看到

    解决方法是将删除的行在订阅中重新插入,主键就是sp_MSins_dboSOMasterExtention里的参数。

    如果在订阅端删除数据,而发布端又更新数据的时候,复制也会报错,如下:

    尝试的命令:
    if @@trancount > 0 rollback tran
    (事务序列号: 0x0001D2A8000005DE001600000000,命令 ID: 1)
    
    错误消息:
    The row was not found at the Subscriber when applying the replicated command. (源: MSSQLServer,错误号: 20598)
    获取帮助: http://help/20598
    The row was not found at the Subscriber when applying the replicated command. (源: MSSQLServer,错误号: 20598)
    获取帮助: http://help/20598

    2、 忽略复制失败的命令
      在复制监视器中可以选中发布服务器 ---在 "操作 '"下拉菜单中可以看到 "代理配置文件 "

    可以看到代理配置文件属性为:

    可以在这个里面进行配置来设置跳过错误,也就是把默认设置改为" Continue on data consistency errors. " 如果设置之后没有的话,可以把代理重新启动。在此不再举例了。

    3、 比较表中的数据差异

    使用sp_browsereplcmds 查询复制出错的语句并手工处理同步失败会比较容易。但如果复制出错误的命令很多,则很难通过上述方法来解决。这种情况下,一般选择忽略复制失败的命令,然后比较发布表的订阅表的数据差异来解决复制 。这个时候可以使用 tablediff 来对数据进行对比生成脚本。tablediff 具体的使用方法可以参看上一篇文章: http://www.cnblogs.com/zerocc/p/3233277.html 。

    对于以上三种方式我提倡的是1和3,第二种方法不太提倡。

  • 相关阅读:
    使用JDBC连接MySql时出现:The server time zone value '�й���׼ʱ��' is unrecognized or represents more than one time zone. You must configure either the server or JDBC driver (via the serverTimezone configuration
    Mysql Lost connection to MySQL server at ‘reading initial communication packet', system error: 0
    mysql-基本命令
    C# 监听值的变化
    DataGrid样式
    C# 获取当前日期时间
    C# 中生成随机数
    递归和迭代
    PHP 时间转几分几秒
    PHP 根据整数ID,生成唯一字符串
  • 原文地址:https://www.cnblogs.com/zerocc/p/3243400.html
Copyright © 2011-2022 走看看