从CDC表

时间:2017-02-17 14:58:50

标签: sql-server

我是一名Java开发人员,我对SQL Server数据库管理员有一点了解。 :)

目标:

编写一个Java程序,按计划,可以根据Changed Data Capture (CDC) ALL SQL Server更改表(CT)中获取数据。< / p>

我创建了一个包含一些表的TEST模式,并在其中几个表上启用了CDC

enter image description here

现在,我可以查询各个CT表并获取数据:

enter image description here

当我想通过Java程序安排这些查询时,挑战就开始了。如查询中所示,我使用时间戳对列tran_begin_time来获取相关的start_lsn,存在一些挑战:

  1. 数据库服务器和托管Java程序的计算机可以有不同的时钟计时,因此,我需要存储tran_begin_time或其他东西,以确保没有数据丢失/导入重复
  2. 在一段时间内,EACH表可以有多个LSN。即使我设法存储所有这些,每个表(这本身很麻烦),我不知道如何在下次执行中使用它们
  3. 我想知道我只应该从cdc.lsn_time_mapping表中存储tran_begin_time和tran_end_time但是我只得到start_lsn,不知何故,我需要回溯到每个CT(更改表)来获取数据(我是真的很担心这个方法) enter image description here
  4. 我还在谈论一个容器数据库(这里是TEST),会有几个这样的
  5. 我该怎么办?

1 个答案:

答案 0 :(得分:1)

正如您可能已经猜测的那样,使用时间会在某些时候导致细微的错误。我建议直接贩卖LSN。 LSN(日志序列号的缩写)是数据库跟踪和命令数据更改的一种方式。 LSN单调增加。这就是我的建议:

  1. 创建一个表来存储您的LSN值以及该间隔的处理是否已完成。像sys.fn_cdc_get_max_lsn()
  2. 之类的东西
  3. 调用(sys.fn_cdc_get_max_lsn(), 0)以获取数据库中的最新LSN。将其存储在表中,其中bit列的值为0(即不完整)
  4. 对于要处理的每个表,从_CT表中选择[__ $ start_lsn]&lt; =(上面的值)
  5. 处理完所有表格后,请将该行标记为完整
  6. 现在您的初始设置已完成。对于正在进行的处理,您将执行以下操作:

    1. 在表格中插入一个值为where [__$start_lsn] > @lower_lsn and [__$start_lsn] <= @upper_lsn的新行。这将是您查询的上边界。
    2. 在表中找到已成功处理的最高LSN值的值。这将代表下限。
    3. 对于每个_CT表,请从中选择<file sed 's/"//10'
    4. 完成所有表格后,将该边界标记为完整。
    5. 如果你这样做,你就不会错过任何数据。