假设我们有两个服务器:服务器 A 和服务器 B。数据正在从 A 复制(普通事务复制)到 B。
对于其中一个表,我们有如下数据:
Server A - Server B
========= =========
ID|Content ID|Content
---------- ----------
1 | ... 1 | ...
2 | ... 2 | ...
... ...
98| ... 98| ...
99| ... 99| ...
一段时间后,我们删除旧数据:
Server A - Server B
========= =========
ID|Content ID|Content
---------- ----------
50| ... 50| ...
51| ... 51| ...
... ...
98| ... 98| ...
99| ... 99| ...
现在,我们改变了复制的顺序,所以现在服务器 B 正在复制到服务器 A。
问题是:
我本以为添加到服务器 B(然后复制到服务器 A)的新数据将继续使用 ID 列(它将转到 100、101、102,...)。相反,我注意到它从 1 开始。
问题是:
当 ID 最终达到 50 时,数据库将如何处理?数据库会开始抛出主键违规,还是会意识到发生了什么,并从 ID 49 跳到 ID 100?
如果它开始抛出主键违规,是否有一个命令可以用来告诉服务器 B 它应该从 ID 100 开始?如果是这样,这个命令可以在复制数据时完成吗?
切换到不同的主服务器后,您必须重新设置身份值,否则您将在 id 列中获得重复项。使用
DBCC CHECKIDENT
语句。SELECT MAX( TID )
通过使用查询并将返回的数字放入动态 SQL 字符串中,可以自动选择数字。这必须放在可序列化的事务中,以确保在此会话重新播种值时没有其他会话插入新行(感谢 David)。此外,在重新播种时不得更改 master。处理此问题的一种方法可能是创建不重叠的身份域。在 ServerA 上,创建身份列为
identity ( 1, 2 )
,在 ServerB 上创建为identity (2, 2 )
。这样,ServerA 的插入将是 1、3、5……,而 ServerB 的插入将是 2、4、6…… 当然,如果您想要创建第三个服务器,那么您将被淹没。:-)更好的是,不要
identity
在多主机情况下使用。它不能防止重复。请改用唯一标识符或应用程序生成的标识符。