Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 并非所有LSN都映射到日期_Sql Server_Cdc - Fatal编程技术网

Sql server 并非所有LSN都映射到日期

Sql server 并非所有LSN都映射到日期,sql-server,cdc,Sql Server,Cdc,我正在构建一个ETL,它处理来自SQLServer的变更数据捕获功能的数据。ETL的一部分是记录有关所处理数据的日志,包括数据导入窗口的开始和结束。为此,我使用sys.fn_map_lsn_To_time函数将用于导入数据的lsn映射到相应的日期时间值 函数sys.fn_cdc_get_all_changes_采用两个参数,即数据导入窗口的开始和结束。这些参数是包含的,因此下一次运行需要增加上一个LSN,以避免重新导入位于边界上的行 显而易见的答案是使用sys.fn_cdc_increment_

我正在构建一个ETL,它处理来自SQLServer的变更数据捕获功能的数据。ETL的一部分是记录有关所处理数据的日志,包括数据导入窗口的开始和结束。为此,我使用sys.fn_map_lsn_To_time函数将用于导入数据的lsn映射到相应的日期时间值

函数sys.fn_cdc_get_all_changes_采用两个参数,即数据导入窗口的开始和结束。这些参数是包含的,因此下一次运行需要增加上一个LSN,以避免重新导入位于边界上的行

显而易见的答案是使用sys.fn_cdc_increment_lsn函数在引入数据之前获取下一个lsn。但是,我发现这个LSN并不总是使用sys.fn_map_LSN_to_time映射到日期时间。LSN在sys.fn_cdc_get_all_change_中有效,但我希望能够轻松准确地记录正在使用的日期

例如:

声明@state_lsn_str CHAR22='0x0000EEE100003E16008F';-请尝试改用'sys.fn\u cdc\u get\u min\u lsn',因为此值不适用于其他任何人 声明@state_lsn BINARY10=CONVERTBINARY10,@state_lsn_str,1; 声明@incr\u lsn BINARY10=sys.fn\u cdc\u增量_lsn@state_lsn; 选择CONVERTCHAR22,@incr_lsn,1作为递增的_lsn, sys.fn\u cdc\u映射到_time@incr_lsn增加日期; 此代码返回的LSN值为0x0000EEE100003E160090,递增的日期为NULL

有没有办法强制LSN映射到时间? 或
有没有一种方法可以在不丢失任何数据的情况下获取下一个确实映射到某个时间的LSN?

sys.fn\u cdc\u increment\u LSN返回的值没有映射到日期时间的原因是没有为该特定LSN记录任何更改。即使没有记录该日期的更改,它也会以尽可能小的值增加LSN

为了解决这个问题,我使用了sys.fn_map_time_To_lsn函数。此函数采用关系运算符参数。您可以通过对此参数使用“最小大于”来获取下一个日期时间值。以下代码返回映射到datetime的下一个LSN:

声明@state_lsn_str CHAR22='0x0000EEE100003E16008F';-请尝试改用'sys.fn\u cdc\u get\u min\u lsn',因为此值不适用于其他任何人 声明@state_lsn BINARY10=CONVERTBINARY10,@state_lsn_str,1; 声明@state\u lsn\u date DATETIME=sys.fn\u cdc\u map\u lsn\u to_time@state_lsn; 声明@next_lsn BINARY10=sys.fn_cdc_map_time_to_lsn'最小大于',@state_lsn_date; 选择CONVERTCHAR22、@next_lsn、1作为next_lsn, sys.fn\u cdc\u映射到_time@next_lsn作为下一个日期; 此代码返回下一个LSN的逻辑日期时间值。尽管我不确定如何100%检查任何其他表中是否没有数据

上述代码的@state_lsn_date值为2018-02-15 23:59:57.447,下一个lsn的值为2018-02-16 00:00:01.363,集成在午夜运行

函数sys.fn_cdc_map_lsn_to_time和sys.fn_cdc_map_time_to_lsn使用cdc.lsn_time_映射表返回结果。此表的文档说明:

为更改表中具有行的每个事务返回一行。 此表用于在日志序列号LSN commit之间进行映射 值和事务提交的时间。参赛作品也可以是 没有变更表条目的已记录。这允许 记录低或低期间LSN处理完成情况的表格 无变化活动

据我所知,这意味着任何更改表中的每个LSN值都将映射到这里。可能会有其他LSN,但不会缺少LSN。这允许代码映射到下一个有效的更改日期

由于所有更改都将在cdc.lsn_time_映射表中进行映射,因此使用此方法不应丢失任何数据

我听起来有点不确定吗?嗯,我是


我希望对SQL Server更改数据捕获系统有更深入了解的人能够确认这是否安全。

我在几次约会中使用了CDC,我想知道为什么能够将LSN映射到某个时间对您很重要。LSN是CDC跟踪其在流中位置的本机方式。Wallclock时间让我们人类感到舒适,但试图让CDC使用它们似乎会招致错误。因此,在成本/收益计算中,有一些成本。通过将LSN映射到时间,可以准确地记录数据导入窗口。这在排除集成问题时非常有用。说上一次运行在两个不可读的二进制值之间导入了数据不是很有用。显示“数据导入”窗口的功能还提高了对数据处理的信任。有时,让人们感到舒适和易于理解日志是有好处的。作为旁白,我实际上使用的是sys.fn\u cdc\u increment\lsn a nd只是声明窗口\u开始\u日期时间值是独占的。这避免了跳过任何LSN,还允许我创建合适的日志。然而,我仍然好奇我的假设是否准确。我没有足够的信心在客户的生产代码中使用它,但我认为它很有趣。