【问题标题】:How do you reload incremental data using SQL Server CDC?如何使用 SQL Server CDC 重新加载增量数据?
【发布时间】:2015-02-24 18:07:34
【问题描述】:

我无法找到有关如何在带有 SSIS 的 SQL Server 2014 中使用变更数据捕获 (CDC) 重新加载增量数据的文档/说明。

基本上,在给定的一天,如果您的 SSIS 增量处理失败并且您需要重新开始。您如何再次暂存最近更改的记录?

【问题讨论】:

    标签: sql-server ssis etl cdc


    【解决方案1】:

    我想这取决于您对数据的处理方式,是吗? :) 不过,在一般情况下,您可以将其分为三种情况:

    1. 插入 - 检查该行是否存在。如果是,请跳过它。如果没有,请插入它。
    2. 删除 - 假设您不重复使用主键,只需再次运行删除。它要么找到要删除的行,要么找不到,但最终结果是删除后具有该 PK 的行将不存在。
    3. 更新 - 有点像删除场景。如果您重新处理更新,这并不是什么大问题(假设您的 CDC 流程是唯一在目的地保持最新状态的东西,并且没有覆盖某人/其他人的更改的危险)。

    【讨论】:

    • 但是 ETL 的第一步 - 从源中获取更改的数据。你如何“重置”它,以便它再次展示这些最近的变化。一旦它在临时数据库中,就很容易处理。但是 CDC - 过程的黑匣子部分让我很难过。如果需要,我想重新暂存相同的数据(手动即可)。
    • 任何 CDC 数据的拉取都以您提供 first_lsn 和 last_lsn 为前提。据推测,在失败的情况下,您只需再次提供相同的端点。
    • 你会怎么做呢?我想这可以分为两个问题:您如何读取 lsn 值?你会如何告诉 SSIS 使用自定义 lsn 范围?
    • 啊……你把控制权交给了一个黑匣子(即 CDC 控制任务)。我不知道它是如何跟踪 LSN 范围的(这就是我上次处理 CDC 时选择不使用它的原因)。不过看起来对你来说是一个很好的学习机会,嗯? :)
    • 他们没有。我建议您阅读msdn.microsoft.com/en-us/library/hh758674.aspx(特别是标题为“处理 CDC 状态持久性”的部分)。另外,我建议忘记 LSN 到时间的映射。这只是一种便利,您可能会丢失交易。 CDC 提供了直接处理 LSN 值的函数,以确保您进行无间隙处理。巧合的是,我昨天写了一个关于这个问题的答案。也检查一下:stackoverflow.com/questions/28675210/…
    【解决方案2】:

    假设您使用的是新的 CDC SSIS 2012 组件,特别是包开头和结尾的 CDC 控制任务。然后,如果包在包末尾运行 CDC 控制任务之前由于任何原因失败,则这些 LSN(日志序列号)将不会被标记为已处理,因此您可以在解决问题后从顶部重新启动 SSIS 包,并且它只会再次重新处理这些记录。您必须使用 CDC 控制任务来完成这项工作,或者自己跟踪 LSN(在 SSIS 2012 之前,这是唯一的方法)。

    Matt Masson(MSFT SQL Server 团队的高级项目经理)在这方面有一篇很棒的帖子,并提供了分步演练:CDC in SSIS for SQL Server 2012

    另外,请参阅 Bradley Schacht 的帖子:Understanding the CDC state Value

    【讨论】:

    • 我确实在 SSIS 2012 中使用 CDC 控制任务设置了它,并且我大部分时间都在工作。我想我问的是你如何“取消标记”这些记录?
    • 此外,有关 CDC 控制任务使用的 CDC 状态的细分以及如何修改它以重新处理 CDC 记录,请参阅 Bradley Schacht 的帖子:bradleyschacht.com/understanding-the-cdc-state-value
    【解决方案3】:

    所以我确实想出了如何在 SSIS 中做到这一点。

    每次我的 SSIS 包在我的数据仓库的表中运行时,我都会记录最小和最大 LSN 编号。

    如果我想将一组数据从 CDC 源重新加载到暂存,我需要在 SSIS 包中使用 CDC 控制任务并将其设置为“标记 CDC 开始”,并在标记为“SQL Server LSN”的文本框中开始....”我把我想要使用的 LSN 值作为起点。

    我还没有弄清楚如何设置端点,但我可以进入我的临时表并删除任何具有 LSN 值的数据 > 然后是我的端点。

    您只能对尚未“清理”的 CDC 更改执行此操作 - 因此仅适用于过去 3 天内已更改的数据。

    顺便说一句,我还将 lsn_time_mapping 表带到我的数据仓库,因为我发现此信息在历史上很有用,并且每 4 天在源数据库中“清理”一次。

    【讨论】:

    • 默认清理作业保留 cdc 数据 3 天,但您可以将默认值更改为您想要的任何值(7 天)
    【解决方案4】:

    要重新加载相同的更改,您可以使用以下方法。

    方法 #1:将 [cdc_states] 表中的 TFEND 标记存储在另一个表或变量中。将标记从“已保存”值重新加载到您的 [cdc_states] 以再次处理相同的范围。但是,此方法允许您从同一个 LSN 开始处理,但如果同时您更改表得到更多更改,这些更改也将被捕获。因此,在您进行第一次数据捕获后,您可能会获得更多的变化。

    方法#2:为了捕获指定范围,记录范围处理前后的TFEND标记。现在,您可以将 OLEDB 源连接 (SSIS) 与以下 cdc 功能一起使用。然后像往常一样使用 CDC 拆分器来指导插入、更新和删除。

    DECLARE @start_lsn binary(10);
    DECLARE @end_lsn binary(10);
    SET @start_lsn = 0x004EE38E921A01000001;-- TFEND (1) -- if null then sys.fn_cdc_get_min_lsn('YourCapture') to start from the beginnig of _CT table
    SET @end_lsn = 0x004EE38EE3BB01000001;  -- TFEND (2)
        SELECT * FROM [cdc].[fn_cdc_get_net_changes_YOURTABLECAPTURE](
         @start_lsn
        ,@end_lsn
        ,N'all' -- { all | all with mask | all with merge }
        --,N'all with mask' -- shows values in "__$update_mask" column
        --,N'all with merge' -- merges inserts and updates together. It's meant for processing the results using T-SQL MERGE statement
        )
    ORDER BY __$start_lsn;
    

    【讨论】:

      猜你喜欢
      • 2020-12-10
      • 1970-01-01
      • 1970-01-01
      • 2020-09-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-12-14
      相关资源
      最近更新 更多