我正在使用 SQL CDC 跟踪 SQL Server 中多个表的更改。我想为每个我有一个从每个 CDC 表中收集数据的程序以正确的顺序报告这些变化。但我想确保这些表发生的所有更改都以正确的顺序报告。我可以依靠 LSN 来获得正确的序列吗?
4 回答
LSN 编号对于给定事务是唯一的,但不是全局唯一的。如果您在同一事务中有多个记录,它们将在 cdc 中共享相同的 __$start_lsn 值。如果您想要正确的操作顺序,您需要按 __$start_lsn、__$seqval 和 __$operation 排序。__$seqval 表示包装事务中单个操作的 id。
例如,我在 dbo 模式中有一个名为 foo 的表。它有一列 y。如果我运行此语句:
INSERT INTO dbo.foo VALUES (1);
INSERT INTO dbo.foo VALUES (2);
然后我将在 cdc 中看到两个单独的 LSN 值,因为它们在两个单独的事务中。如果我运行这个:
BEGIN TRAN
INSERT INTO dbo.foo VALUES (1);
INSERT INTO dbo.foo VALUES (2);
COMMIT TRAN
然后我将看到两条记录的一个 LSN 值,但它们将具有不同的 __$seqval 值,并且我的第一条记录的 seqval 将小于我的第二条记录的 seqval。
LSN 在该数据库中的所有表中是唯一的,并且在数据库中不断增加。
在大多数情况下,LSN 值在所有表中都是唯一的,但是我发现一个 LSN 值属于 40 个表中的更改的实例。我不知道与这些更改相关的 SQL 脚本,但我知道所有操作都是“插入”。
不确定这是否是一个错误。CDC 文档很差,只涵盖基础知识。没有多少用户知道 CDC 捕获过程有许多由 MS 确认的 SQL 2014 和 2016 错误(我们有开放案例)。
所以我不会依赖文档。在某些情况下可能是错误的。最好实施更多检查并使用大量不同的更改组合对其进行测试。
我也遇到过这种情况。根据我的经验和我的理解,在您的第一个示例中,发生了 2 笔交易,因此您将真正获得 2 个不同的 LSN。在您的第二个示例中,您只有 1 个事务,其中包含 2 个查询。由于它位于 BEGIN 和 END TRAN 之内,CDC 会将其仅计为 1 个事务。由于这是我的个人经历,我无法提供给您的链接。