0

我是 SQL Server 的初学者。对于一个项目,我需要打开 CDC。我将 cdc 数据复制到另一个(存档)数据库,之后可以立即清理 CDC 表。所以保留时间不需要很长,我只是把它放在 1 分钟,当清理作业运行时(在保留时间已经完成之后),它似乎只删除了几条记录(最旧的记录)。为什么不删除所有内容?有时它根本不会删除任何东西。运行该作业几次后,其他记录将被删除。我觉得这很奇怪,因为保留时间已经过去了。

我将保留时间设置为 1 分钟(我实际上想要 0,但这是不可能的)并且没有更改阈值(= 5000)。我禁用了计划,因为我希望在将 CDC 记录复制到我的存档数据库后立即运行清理作业,而不是在特定时间运行。

我对这个想法的逻辑是,例如下午会有更新。将 CDC 记录复制到存档数据库的任务应在凌晨 2:00 运行,在此任务之后将调用清理作业。因此,由于最短保留时间,清理作业应删除所有 CDC 记录。保留时间到底过了?

我只是想看看当我在工作中再次设置时间表时发生了什么,比如 CDC 的一般用途。时间过去后,我检查了 CDC 表,结果发现它也只删除了最旧的记录。那么我做错了什么?

我做了一个解决方法,我做了一个新工作,任务是删除 CDC 表中的所有记录(并禁用整个默认的 CDC 清理工作)。这会更好,因为它可以删除所有内容,但这让我很困扰,因为我想使用原始的清理工作,并且我认为它应该能够以我想要的方式工作。

谢谢,

4

1 回答 1

0

我不必担心表中的内容,而是使用为每个捕获实例创建的辅助函数。具体来说,cdc.fn_cdc_get_all_changes_ 和 cdc.fn_cdc_get_net_changes_。我使用的典型工作流程如下(对所有捕获实例执行此操作)。首先,您需要一个表格来保持处理状态。我使用类似的东西:

create table dbo.ProcessingStatus (
   CaptureInstance sysname,
   LSN numeric(25,0),
   IsProcessed bit
)
create unique index [UQ_ProcessingStatus] 
   on dbo.ProcessingStatus (CaptureInstance) 
   where IsProcessed = 0
  1. 使用 fn_cdc_get_max_lsn 获取当前最大日志序列号 (LSN)。
  2. 获取最后处理的 LSN 并使用 fn_cdc_increment_lsn 递增它。如果您没有(即这是您第一次处理),请为此实例使用 fn_cdc_get_min_lsn 并使用它(但不要增加它!)。记录您在表中使用的任何 LSN,设置 IsProcessed = 0。
  3. 从 cdc.fn_cdc_get... 函数中选择对您的方案有意义的任何一个,然后处理结果,但您将要处理它们。
  4. 为此运行更新 IsProcessed = 1。

至于监控你的原始问题,只要确保捕获表中的数据一般在保留期内即可。也就是说,如果您将其设置为 2 天,我什至不会认为这是一个问题,直到超过 4 天(假设您对清理作业的调用安排在每小时一次)。而当你使用上述方案进行处理时,你不必担心那里有“太多”的数据;你总是在处理一个特定的时间间隔而不是“一切”。

于 2014-08-14T17:49:15.647 回答