SQL CDC数据处理选项

时间:2015-02-23 13:46:12

标签: sql-server service-broker cdc change-data-capture

我在几个表上设置了SQL Server CDC。一旦CDC被启动,就会填充cdc表。我希望处理这些更改并为发生的每次更改生成MQ消息,以将其发送到外部消息队列。

处理此数据的最佳方法是什么。我看过像sqdata这样的产品,但我在想是否有更好的方法。我查看了带有服务代理的CDC,但这会生成要发送到外部应用程序的消息。

我的另一个问题是当CDC更改生成消息时我希望它删除更改数据,这样如果我想扩展此处理服务,那么它就不应该处理已处理的数据。

2 个答案:

答案 0 :(得分:1)

使用的CDC取决于使用LSN来查找您在流中处理的内容。您需要跟踪您以某种方式处理的间隔(我喜欢将它们粘贴在数据库的表中)。该表看起来像:

create table dbo.CDCProcessing (
   ID int identity not null,
   CaptureInstance sysname not null,
   FarEndpoint binary(10),
   IsProcessed bit
);

create unique index [OnlyOneOpenRange] 
on dbo.CDCProcessing (CaptureInstance)
where IsProcessed = 0;

您的处理循环将类似于以下内容(对于每个捕获实例):

  1. 检查CDCProcessing表中可能中止的处理间隔(即" where IsProcessed = 0"
  2. 如果从上述步骤中找不到间隔,请插入一个。对于FarEndpoint的值,请使用sys.fn_cdc_max_lsn()的值。如果您找到了它,就像使用它一样自己插入它。
  3. 根据您的具体情况,使用cdc.fn_cdc_get_all_changes_<capture_instance>cdc.fn_cdc_get_net_changes_<capture_instance>处理时间间隔。无论哪种方式,您都需要from_lsn的值。如果dbo.CDCProcessing表具有此CaptureInstance的行,请获取具有最大FarEndpoint值的行并在其上调用sys.fn_cdc_increment_lsn。如果没有行,请为此捕获实例调用sys.fn_cdc_get_min_lsn
  4. 成功处理完所有行后,将IsProcessed列更新为1,以获取未处理的时间间隔。
  5. 如果您处于间隔中间并且中止,那么上述情况就会非常愚蠢。也就是说,您最终可能会多次处理一些CDC记录。如果这对您很重要,您可以修改该过程以考虑下游系统处理的最后一条消息,并相应地更新CDCProcessing表。但这仍然是读者的一种练习。

    至于你关于清除的其他问题,那不是很有效。设置CDC时,应创建一个保持滚动间隔的作业(我认为默认值为3天)。作业定期运行并将CDC数据修剪为保留间隔。因此,假设该工作运行,您不必担心它。

答案 1 :(得分:0)

最近我使用虚拟cdc实例创建了一个解决方案(使用单个真实捕获实例,无限数量的独立和不同实例可以作用于单个目标表,这是我需要克服的问题之一。

我的解决方案是使用持久数据表从CT表接收数据,然后从那里处理数据。通过使用每30秒运行一次的作业以及存储实例名称和最后一个LSN的表来设置它,我可以将数据分配到持久存储中,可以在同一客户端数据库上,也可以在单独的公共数据库上(打开或关闭相同的sql实例)。

这允许我指定清理并随时减少本地存储的数据量。

对于处理方面,这将需要您使用在创建实例时创建的cdc函数。通过使用[ $ update_mask]列,您可以确定实际的列更改,并简单地将这些值与[ $ start_lsn] /一起拉出(尽管操作1,2或3/4) __ $ seqval,timestamp(来自LSN)。

要解密update_mask列和Timestamp,您可以使用以下代码:

null