最近帮一个客户搭建跨洋的合并复制,由于数据库非常大,跨洋网络条件不稳定,因此只能通过备份初始化,在初始化完成后向海外订阅端插入数据时发现报出如下错误:

Msg 548, Level 16, State 2, Line 2
The insert failed. It conflicted with an identity range check constraint in database %s, replicated table %s, column %s. If the identity column is automatically managed by replication, update the range as follows: for the Publisher, execute sp_adjustpublisheridentityrange; for the Subscriber, run the Distribution Agent or the Merge Agent.

 

原因?

    在SQL Server中,对于自增列的定义是对于每一条新插入的行,都会自动按照顺序新生成一个递增的数字,改数字通常和业务无关且被用于作为主键。但如果该表用于可更新事务复制或者合并复制,那么该自增列的区间范围则由复制管理。

    此时,复制可以保证自增列可控,因为复制代理插入行时不会导致自增列自增,只有用户显式插入时才会导致自增列自增。

    让我们来做一个实验。首先创建表,表定义如下:

CREATE TABLE [dbo].[Table_1](

    [c1] [int] IDENTITY(1,1),

    [c2] [int] NULL,

    [ROWGUID] [uniqueidentifier] NOT NULL,

    [rowguid4] [uniqueidentifier] ROWGUIDCOL  NOT NULL,

 CONSTRAINT [PK_Table_1] PRIMARY KEY CLUSTERED 

(

    [c1] ASC

)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]

) ON [PRIMARY]

 

    此时我们对创建合并复制,并把该表包含在内,并使用快照代理初始化复制,当完成该步骤时,我们发现该表上自动多了两个约束,如图1所示。

图1.合并复制所加的约束

    

     我们看到该约束的定义只允许4002到5002以及5002到6002之间的数据被插入。

     此时如果出现了一些BUG或者人为改动了该表自增列种子的值,则会报错,如图2所示。

图2.改动种子值导致插入数据出错

 

    该约束会由合并代理自动递增,比如说我们用如下代码插入2000条数据,则发现该约束会自动递增如图3所示。

DECLARE @index INT=1

WHILE @index<2000

BEGIN

INSERT INTO table_1(c2,ROWGUID) VALUES(2,NEWID())

SET @index=@index+1

END

  

   图3.约束区间自动递增滑动

 

解决办法  

    此时我已经找出了上面报错的原因,因为是由于从备份初始化,那么备份以及备份传输期间发布库又有新的数据插入,此时发布库比如说,该表的种子大小已经增加到了6000,而备份中该表大小还是5000,而约束已经滑动到了6000,那么在订阅端插入数据时就会发生这种问题。

解决办法1

    在发布端使用sp_adjustpublisheridentityrange 存储过程使得约束范围自动向后滑动,比如从6000-8000滑动到8000-10000。缺点自增值之间会有一个GAP。如果业务允许,推荐使用该做法。

    sp_adjustpublisheridentityrange @table_name=’表名称‘

解决办法2

    在发布端运行SELECT  IDENT_CURRENT('表名称'),找到发布表的种子值。在订阅端通过DBCC CHECKIDENT (表名称,RESEED, 设置为上面值)命令将两端种子值设置为一致。

解决办法3

    在订阅端运行合并代理,即可修复数据。如果此方法不行,则再次尝试上述方法。

解决办法4

    不用自增列,而使用GUID列,但这涉及到表结构以及程序的修改,而且需要重新初始化复制,因此不是每一个环境都有条件这么做。

   

此时,就可以正常插入数据了。

SQL Server 合并复制遇到identity range check报错的解决的更多相关文章

  1. SQL Server 合并复制遇到identity range check报错的解决 (转载)

    最近帮一个客户搭建跨洋的合并复制,由于数据库非常大,跨洋网络条件不稳定,因此只能通过备份初始化,在初始化完成后向海外订阅端插入数据时发现报出如下错误: Msg 548, Level 16, State ...

  2. Sql Server 2008卸载后再次安装一直报错

    sql server 2008卸载之后再次安装一直报错问题. 第一:由于上一次的卸载不干净,可参照百度完全卸载sql server2008 的方式 1. 用WindowsInstaller删除所有与S ...

  3. SQL server 维护计划中 “清除维护任务” 执行报错

    SQL server 维护计划中 “清除维护任务” 执行报错,错误如下: 执行查询“EXECUTE master.dbo.xp_delete_file 0,N'',N'',N'2019...”失败,错 ...

  4. SQL Server 合并复制的Article可以指定单个对象的更新方向

    如下所示,这是SQL Server中一个合并复制发布端的Article: 我们可以在Article中选择一个对象,比如这里我们选择MD.Car表,点击鼠标右键,选择"Set Properti ...

  5. SQL Server 合并复制如何把备份的发布端或订阅端BAK文件还原为数据库

    SQL Server的合并复制,是可以备份发布端和订阅端数据库为BAK文件的,但是问题是合并复制在数据库中自动创建的系统表.触发器.表中的RowGuid列等也会被一起备份. 这里我们举个例子,下面图中 ...

  6. 关于SQL Server 各种安装失败均失败,报错“等待数据库引擎恢复句柄失败”的经验分享

    最近安装SQL 2019遇到这个问题,试过自己合网上几乎所有办法,怎么都安装不上,最后在微软社区解决了,由于这个问题比较特殊,并且网上几乎没有正确的决绝方案,因此将我的解决过程及经验记录分享一下,也为 ...

  7. Ubuntu Server 上安装pip后pip命令报错的解决办法

    Installation Do I need to install pip? pip is already installed if you are using Python 2 >=2.7.9 ...

  8. SQL Server2008数据库报错与解决方法

    一. 报错信息 启动MSSQLSERVER时有以下报错信息 打开SQL SERVER配置管理器,发现以下情况报错: 原因:由于先前安装了2005版VS,然后又安装了2015版VS 解决办法:卸载Loc ...

  9. SQL Server 2012复制教程以及复制的几种模式

    简介 SQL Server中的复制(Replication)是SQL Server高可用性的核心功能之一,在我看来,复制指的并不仅仅是一项技术,而是一些列技术的集合,包括从存储转发数据到同步数据到维护 ...

随机推荐

  1. Centos6.5下编译安装mysql 5.6

    一:卸载旧版本 使用下面的命令检查是否安装有MySQL Server rpm -qa | grep mysql 有的话通过下面的命令来卸载掉 rpm -e mysql //普通删除模式 rpm -e ...

  2. 【资源】.Net 入门@提高 - 逆天的高薪之路!

     入门看视频,提高看书籍,飘升做项目.老练研开源,高手读外文,大牛讲低调~    官方学习计划 http://www.cnblogs.com/dunitian/p/5667901.html ----- ...

  3. Golang 编写的图片压缩程序,质量、尺寸压缩,批量、单张压缩

    目录: 前序 效果图 简介 全部代码 前序: 接触 golang 不久,一直是边学边做,边总结,深深感到这门语言的魅力,等下要跟大家分享是最近项目 服务端 用到的图片压缩程序,我单独分离了出来,做成了 ...

  4. SignalR系列目录

    [置顶]用SignalR 2.0开发客服系统[系列1:实现群发通讯] [置顶]用SignalR 2.0开发客服系统[系列2:实现聊天室] [置顶]用SignalR 2.0开发客服系统[系列3:实现点对 ...

  5. C#项目中文件的具体含义

    1.Bin 目录 用来存放编译的结果,bin是二进制binary的英文缩写,因为最初C编译的程序文件都是二进制文件,它有Debug和Release两个版本,分别对应的文件夹为bin/Debug和bin ...

  6. .NET应用和AEAI CAS集成详解

    1 概述 数通畅联某综合SOA集成项目的统一身份认证工作,需要第三方系统配合进行单点登录的配置改造,在项目中有需要进行单点登录配置的.NET应用系统,本文专门记录.NET应用和AEAI CAS的集成过 ...

  7. JAVA构造时成员初始化的陷阱

    让我们先来看两个类:Base和Derived类.注意其中的whenAmISet成员变量,和方法preProcess(). 情景1:(子类无构造方法) class Base { Base() { pre ...

  8. JavaScript求两个数字之间所有数字的和

    这是在fcc上的中级算法中的第一题,拉出来的原因并不是因为有什么好说的,而是我刚看时以为是求两个数字的和, 很显然错了.我感觉自己的文字理解能力被严重鄙视了- -.故拉出来折腾折腾. 要求: 给你一个 ...

  9. SVN的使用

  10. 排序算法----调用库函数qsort进行快速排序

    功 能: 快速排序 头文件:stdlib.h 用 法: void qsort(void *base,int nelem,int width,int (*fcmp)(const void *,const ...