繁体   English   中英

如何在 SQL Server 中完全自动化 CDC?

[英]How to fully Automate CDC in SQL Server?

有没有办法在活动的 SQL Server 数据库中 100% 自动化 SQL Server CDC 初始化? 我正在尝试解决在第一次 cdc 数据捕获期间发现from_lsn的问题。

事件顺序:

  1. 在给定的数据库/表上启用 CDC
  2. 将完整表复制到目标(数据湖)
  3. 使用 CDC 捕获第一个增量(我想避免重复,而不会丢失事务)

问题:

  • 如何获取 fn_cdc_get_all_changes_Schema_Table( from_lsn fn_cdc_get_all_changes_Schema_Table(from_lsn, to_lsn, '<row_filter_option>')函数的 from_lsn

笔记:

  • 需要 100% 自动化
  • 无法停止表上的事务
  • 不能遗漏任何数据或不能承受重复数据

在进行初始加载之前,获取fn_cdc_get_max_lsn()的值并存储它。 此函数返回所有捕获实例中 CDC 已知的最高 LSN。 这是整个数据库的高水位线。

复制整个表格。

开始您的增量过程。 第一次调用 delta 函数时, min_lsn参数的值将是之前从fn_cdc_get_max_lsn()检索到的存储值。 fn_cdc_get_max_lsn()获取当前值(不是存储的)并将其用作max_lsn参数的值。

从这里按您的预期进行。 获取从 delta 函数返回的最大 LSN,存储它。 下次拉增量时,对存储的值使用fn_cdc_increment_lsn ,将结果用作min_lsn参数的值,并将fn_cdc_get_max_lsn()的结果用作max_lsn参数。

通过此过程,您将永远不会错过任何数据。

现在,您提到要避免“重复”。 但是,如果您尝试在这种情况下定义“重复”是什么,我认为您会发现它很困难。

例如,假设我有这个表开始:

create table t(i int primary key, c char);
insert t(i, c) values (1, 'a');
  1. 我调用fn_cdc_get_max_lsn()并得到0x01
  2. 用户向表中插入新行: insert t(i, c) values (2, 'b');
  3. 用户操作与0x02的 LSN 值相关联。
  4. 我选择了这个表中的所有行(得到两行)。
  5. 我将两行都写入我的目标表。
  6. 我开始我的增量过程。 我的min_lsn参数将是0x01

因此,我将在增量中获得{2, 'b'}行。

但我已经检索了行{2, 'b'}作为初始加载的一部分。 这是“重复”吗? 不,这代表对表格的更改 当我将这个增量加载到我的目的地时,我将如何处理它? 实际上只有两种选择。

选项 1:我将根据主键将增量合并到目标表中。 在这种情况下,当我合并增量时,我将用新行{2, 'b'}覆盖已经加载的行{2, 'b'} , 'b'} ,其结果看起来与不做任何事情相同。

选项 2:我要将所有更改附加到目的地。 在这种情况下,我的目标表将包含行{2, 'b'}两次。 这是重复的吗? ,因为这两行代表数据在不同逻辑时间的外观。 首先是当我进行初始加载时,然后是当我进行增量时。

如果您试图争辩这实际上是重复的,那么我通过给您这个假设场景来反驳:

  1. 您进行初始加载,接收行{1, 'a'}
  2. 没有用户更改任何数据。
  3. 你得到你的第一个增量,它是空的。
  4. 用户执行update T set c = 'b' where i = 1
  5. 您将获得第二个增量,其中将包括行{1, 'b'}
  6. 用户执行update T set c = 'a' where i = 1
  7. 您将获得第三个增量,其中将包括行{1, 'a'}

问题:您在第三个增量期间检索到的行是“重复的”吗? Is 与我们之前检索到的行具有相同的值。

如果您的回答是“是”,那么您将永远无法消除“重复”读取,因为只要一行发生突变以具有与之前某个时间点相同的值时,就会发生“重复”,这是您在无法控制。 如果这是您需要在追加方案中消除的“重复项”,则必须通过将传入值与现有值进行比较,在目的地执行消除。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM