【问题标题】:Change Data Capture For Updates and Deletes Only仅用于更新和删除的更改数据捕获
【发布时间】:2012-09-11 21:58:56
【问题描述】:

我们的数据库插入不密集(每晚 200-500k),但更新光照(可能每天几百)。

我需要无限期地保留对插入行本身所做的所有更改的历史记录(但不是实际插入)。我很想使用更改数据捕获,但支持此功能所需的空间量不可用。如果我能想办法做到以下几点,我的生活会轻松很多。

1) 将更改数据跟踪限制为仅更新和删除 2) 定期从 CDC 表中清除 INSERTS

在过去,我只是使用了一个触发器(它仍然没有被排除在外!)。

【问题讨论】:

    标签: sql-server-2008 change-data-capture


    【解决方案1】:

    我只会使用触发器来捕获更新和删除。

    我不认为你可以告诉 CDC 需要注意什么 DML,而且我认为让 CDC 记录所有这些插入然后删除它们是相当浪费的。这本身就很昂贵,并且它会导致的碎片也会导致您对捕获表运行的任何查询(您将有很多大部分为空的页面)以及工作统计信息必须不断做保持最新的统计数据。

    您可以在捕获表上放置一个而不是插入触发器,它什么都不做,但我没有尝试这样做甚至查看它是否被允许,我当然不知道这会产生什么影响对CDC的功能。可能值得进行一些调查,但即使这个 hack 确实有效,我的原始答案仍然有效:只需使用触发器。

    【讨论】:

    • 谢谢亚伦...这几乎就是我的思绪。我真的希望将来允许对 CDC 进行更细粒度的控制。
    • 我不确定在自己实现 _CT 表时是否需要考虑碎片。根据更改量,您可以制定最佳解决方案。就其价值而言,触发器只是事务的扩展,并且是同步的,与异步相反,它们有自己的风险。 CDC 提供了许多方面,因此您不能简单地确定要捕获哪些操作,您应该在任何情况下尽早清除 _CT 表并将数据卸载到暂存数据库或您的审计数据库中。
    • 显然,您永远不需要通过操作从 _CT 表中删除行,因为您可以确定将提取哪些操作并忽略那些您不需要的操作,无论操作如何,在清理表之前,任何解决方案都应该放在首位的政策。我们每周在维护期间完成对 CDC 实例的刷新,因此使用 CDC 对客户端系统进行所有审计或报告时没有遇到减速或其他问题。
    【解决方案2】:

    如果空间是一个考虑因素,您始终可以将 CDC 表分配给可能存在于不同服务器上的不同文件组。你可以这样做:

     ALTER DATABASE YourDatabase
     ADD FILEGROUP [cdc_ChangeTables];
     go
    
     --this step requires going on to somewhere on your hard drive and creating a folder
     ALTER DATABASE YourDatabase
     ADD FILE ( NAME = N'cdc_ChangeTables',
                FILENAME = N'E:\NameOfFolderYouSetUp\YourDatabase_cdc_ChangeTables.mdf',
                SIZE = 1048576KB,
                FILEGROWTH = 102400KB )
     TO FILEGROUP [cdc_ChangeTables];
     GO
    

    然后,当您要设置 CDC 表时,请将它们指向该文件组:

    EXEC sys.sp_cdc_enable_table
        @source_schema = N'dbo',
        @source_name = N'TableYouWantToCapture',
        @role_name = N'cdc_admin',
        @filegroup_name = N'cdc_ChangeTables', --this is where you name the filegroup from previous step
        @supports_net_changes = 1,  
        @capture_instance = N'dbo_TableYouWantToCapture',
        @captured_column_list = 'ColumnName1, ColumnName2'; --comma-delimited list of column names
    GO
    

    如果你只想查询更新/删除,你可以像这样使用系统函数:

    SELECT * 
    FROM cdc.fn_cdc_get_all_changes_dbo_TableYouWantToCapture(@from_lsn, @to_lsn, N'all update old')
    WHERE __$operation IN (1,3,4)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-13
      • 2017-03-11
      • 2021-11-15
      • 2021-09-16
      • 2016-05-12
      相关资源
      最近更新 更多