rowversion在0xFF后跳过一个整数

时间:2018-03-16 00:00:55

标签: sql-server sql-server-2012

根据rowversion docs

  

每个数据库都有一个计数器,该计数器针对在数据库中包含rowversion列的表上执行的每个插入或更新操作递增。

然而,当从FF循环回到01时,这个'增量'会跳过一个整数。例如

0x00000000000007FF
0x0000000000000801

要重现,请创建一个表

CREATE TABLE [dbo].[TestTable](
[Id] [bigint] IDENTITY(1,1) NOT NULL,
[SomeData] [varchar](200) NOT NULL,
[RowVersion] [rowversion]  not null
) ON [PRIMARY]

现在添加一些插页:

DECLARE @i INT = 0

WHILE @i < 256
BEGIN
    SET @i = @i + 1

  INSERT INTO [TestTable] ([SomeData]) VALUES (CONVERT(VARCHAR(255), NEWID()))    
END

查看数据:

select * from [TestTable] order by [RowVersion] asc

根据您是否使用过rowversion,数据会有所不同 在这种情况下我们看到2047(0x00000000000007FF)跳转到2049(0x0000000000000801)

为什么会这样?

enter image description here

2 个答案:

答案 0 :(得分:2)

引用的文档提到rowversion值是唯一的,二进制的和递增的。它并没有说会有差距。该值旨在用于乐观并发验证,因此间隙对于此目的无关紧要。

答案 1 :(得分:0)

这是rowversion(timestamp)的内部实现。该实施允许设计上的差距。

例如,让我们看看数据库备份/恢复如何影响它。

最大rowversion的值存储在数据库引导页面中。生成每个新的rowversion时,该值不会更改。相反,SQL引擎保留了几千行版本并对其进行更新,例如从20,000到24,000。如果还原数据库或数据库脱机,则会丢失20,000..24,000的范围。新行版本将从24,000

开始

因此,您的代码绝不应该依赖于没有间隙的假设。

您可以检查最后保存的rowverion值:

DBCC TRACEON (3604);
DBCC DBINFO ('db-name')

并寻找'dbi_maxDbTimestamp'