重新启动 SQL Server 时标识值跳转

Alo*_*ahi 6 sql-server identity sql-server-2012

我们刚刚从 SQL Server 2008 R2 切换到 SQL Server 2012。我遇到了标识列的问题:

每当我重新启动 SQL Server 时,每个标识列的种子值都会增加 1000(对于int标识列是 1000,对于bigint它是 10,000)。例如,如果表的下一个int标识值是 3,那么在重新启动 SQL Server 后它将是 1003。如果我再次重新启动 SQL Server,它将是 2003,以此类推。

在谷歌搜索后,我发现它是 SQL Server 2012 中的一个新功能(不知道它的用途),如果您想要旧的身份行为,只有两种解决方案:

  1. 使用序列对象

    这对我来说是不可能的,因为:

    a) 我在 SQL Server 2008 和 2012 中使用相同的数据库。我不能在 2008 中使用序列。

    b) 如果我使用序列,那么我需要更改每个表的保存过程,这对我们来说将是一项繁重的任务。

  2. 使用跟踪标志 272 (-T272)

    我可以使用此解决方案,因为无需对我的应用程序进行任何更改。有人建议添加-T272作为启动参数,之后此 SQL Server 标识将像在以前的版本中一样工作。我做了同样的事情,但它不起作用。

我不想对我的数据库结构进行任何更改。请提出解决方案或解释为什么-T272不起作用。

Pau*_*ite 13

我发现它是一个新功能(不知道它有什么用)

在 SQL Server 2012 之前,标识分配总是单独记录(因为每个值都被使用)。在短时间内生成许多标识值的情况下,这种每行日志记录活动可能会限制吞吐量。为提高效率,SQL Server 2012(及更高版本)仅记录一批标识值的分配。分配的范围被缓存并按需发布,直到需要新的一批值。

如果在关闭时没有检查包含标识对象的数据库的情况下重新启动 SQL Server,则缓存范围中任何剩余的未使用值都将丢失,从而导致重新启动时值发生跳转。

不幸的是,关闭 SQL Server 2012 的常用方法目前不会自动检查点数据库(这与文档相矛盾,因此应该在将来的某个时候修复)。为避免在 SQL Server 2012 上分配的标识值发生跳跃的这种特殊原因,请始终使用T-SQL命令SHUTDOWN(不带NOWAIT选项)关闭 SQL Server 。

SHUTDOWN命令将在关闭服务器之前正确检查所有用户数据库。千万不能使用Windows服务控制应用程序,SQL Server配置管理器时,SQL Server Management Studio中的用户界面,或任何其他方法。

您还可以CHECKPOINT在使用任何其他方法关闭 SQL Server 之前手动操作所有数据库,但这要求您确保在检查点之后和关闭完成之前,任何数据库中都没有发生身份分配活动。这可能不容易可靠地实现。

卡伦·德莱尼 (Kalen Delaney) 的《迷失身份》中的更多信息和背景。


跟踪标志 272 现在记录在DBCC TRACEON - Trace Flags (Transact-SQL) 中

禁用身份预分配以避免在服务器意外重新启动或故障转移到辅助服务器的情况下身份列的值出现间隙。请注意,标识缓存用于提高具有标识列的表的 INSERT 性能。

注意:从 SQL Server 2017 开始,要在数据库级别完成此操作,请参阅ALTER DATABASE SCOPED CONFIGURATION (Transact-SQL) 中的 IDENTITY_CACHE 选项。

范围:仅限全球