SQL Server 合并复制遇到identity range check报错的解决

本文涉及的产品
RDS SQL Server Serverless,2-4RCU 50GB 3个月
推荐场景:
云数据库 RDS SQL Server,基础系列 2核4GB
简介:
    最近帮一个客户搭建跨洋的合并复制,由于数据库非常大,跨洋网络条件不稳定,因此只能通过备份初始化,在初始化完成后向海外订阅端插入数据时发现报出如下错误:

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所示。

image

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

    

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

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

image

图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
  

image
   图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 Replication


本文转自CareySon博客园博客,原文链接:http://www.cnblogs.com/CareySon/p/4778854.html如需转载请自行联系原作者
相关实践学习
使用SQL语句管理索引
本次实验主要介绍如何在RDS-SQLServer数据库中,使用SQL语句管理索引。
SQL Server on Linux入门教程
SQL Server数据库一直只提供Windows下的版本。2016年微软宣布推出可运行在Linux系统下的SQL Server数据库,该版本目前还是早期预览版本。本课程主要介绍SQLServer On Linux的基本知识。 相关的阿里云产品:云数据库RDS&nbsp;SQL Server版 RDS SQL Server不仅拥有高可用架构和任意时间点的数据恢复功能,强力支撑各种企业应用,同时也包含了微软的License费用,减少额外支出。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/sqlserver
相关文章
|
3月前
|
SQL 关系型数据库 MySQL
这样的SQL执行为什么不会报错?optimizer_trace深度历险
【10月更文挑战第12天】本文探讨了一条看似错误但实际上能成功执行的SQL语句,通过开启MySQL的优化器追踪功能,详细分析了SQL的执行过程,揭示了子查询被优化器解析为连接操作的原因,最终解释了为何该SQL不会报错。文章不仅增进了对SQL优化机制的理解,也展示了如何利用优化器追踪解决实际问题。
|
4月前
|
SQL 数据库
数据库数据恢复—SQL Server数据库报错“错误823”的数据恢复案例
SQL Server附加数据库出现错误823,附加数据库失败。数据库没有备份,无法通过备份恢复数据库。 SQL Server数据库出现823错误的可能原因有:数据库物理页面损坏、数据库物理页面校验值损坏导致无法识别该页面、断电或者文件系统问题导致页面丢失。
126 12
数据库数据恢复—SQL Server数据库报错“错误823”的数据恢复案例
|
4月前
|
SQL 数据库
SQL解析相关报错
SQL解析相关报错
55 5
|
5月前
|
XML SQL 数据格式
XML动态sql查询当前时间之前的信息报错
XML动态sql查询当前时间之前的信息报错
63 2
|
5月前
|
SQL 分布式计算 DataWorks
DataWorks操作报错合集之新建项目的元数据的sql报错,如何解决
DataWorks是阿里云提供的一站式大数据开发与治理平台,支持数据集成、数据开发、数据服务、数据质量管理、数据安全管理等全流程数据处理。在使用DataWorks过程中,可能会遇到各种操作报错。以下是一些常见的报错情况及其可能的原因和解决方法。
|
2月前
|
SQL 存储 PHP
解决高版本laravel/framework中SQLServer2008分页报错问题
【11月更文挑战第15天】在高版本的Laravel框架中,使用SQLServer 2008数据库进行分页操作时可能会遇到兼容性问题,导致报错。本文提供了两种解决方案:一是升级数据库版本至2012或更高,以提高对复杂查询的支持;二是通过自定义分页查询构建器,手动调整分页逻辑,使其适应SQLServer 2008的特性。具体实施步骤包括备份数据、安装新数据库版本、恢复数据,或创建自定义分页查询类并在模型中使用。这些方法能有效解决分页报错问题。
|
2月前
|
SQL PHP 数据库
解决高版本laravel/framework中SQLServer2008分页报错问题
【11月更文挑战第6天】在高版本的 `laravel/framework` 中使用 SQL Server 2008 进行数据库操作时,可能会出现分页报错。这是由于 `laravel` 的分页机制与 SQL Server 2008 的某些特性不兼容所致。解决方法包括:1. 升级数据库版本;2. 自定义分页查询语句;3. 使用兼容包或插件;4. 修改 `laravel` 的分页逻辑。
|
3月前
|
SQL 关系型数据库 MySQL
|
4月前
|
关系型数据库 MySQL Nacos
nacos启动报错 load derby-schema.sql error
这篇文章描述了作者在使用Nacos时遇到的启动错误,错误提示为加载derby-schema.sql失败,作者通过将数据库从Derby更换为MySQL解决了问题。
nacos启动报错 load derby-schema.sql error
|
4月前
|
关系型数据库 MySQL Java
flywa报错java.sql.SQLSyntaxErrorException: Unknown database ‘flyway‘
flywa报错java.sql.SQLSyntaxErrorException: Unknown database ‘flyway‘
47 1