我在几个表上设置了SQL Server CDC。一旦CDC被启动,就会填充cdc表。我希望处理这些更改并为发生的每次更改生成MQ消息,以将其发送到外部消息队列。
处理此数据的最佳方法是什么。我看过像sqdata这样的产品,但我在想是否有更好的方法。我查看了带有服务代理的CDC,但这会生成要发送到外部应用程序的消息。
我的另一个问题是当CDC更改生成消息时我希望它删除更改数据,这样如果我想扩展此处理服务,那么它就不应该处理已处理的数据。
答案 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;
您的处理循环将类似于以下内容(对于每个捕获实例):
where IsProcessed = 0
" sys.fn_cdc_max_lsn()
的值。如果您找到了它,就像使用它一样自己插入它。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
。如果您处于间隔中间并且中止,那么上述情况就会非常愚蠢。也就是说,您最终可能会多次处理一些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