我们的数据库插入不密集(每晚 200-500k),但更新光照(可能每天几百)。
我需要无限期地保留对插入行本身的所有更改的历史记录(但不是实际的插入)。我很想使用更改数据捕获,但支持此功能所需的空间量不可用。如果我能想办法做到以下几点,我的生活会容易得多。
1) 将更改数据跟踪限制为仅 UPDATES 和 DELETES 2) 定期从 CDC 表中清除 INSERTS
在过去,我只是使用了一个触发器(它仍然没有被排除在外!)。
我们的数据库插入不密集(每晚 200-500k),但更新光照(可能每天几百)。
我需要无限期地保留对插入行本身的所有更改的历史记录(但不是实际的插入)。我很想使用更改数据捕获,但支持此功能所需的空间量不可用。如果我能想办法做到以下几点,我的生活会容易得多。
1) 将更改数据跟踪限制为仅 UPDATES 和 DELETES 2) 定期从 CDC 表中清除 INSERTS
在过去,我只是使用了一个触发器(它仍然没有被排除在外!)。
我只会使用触发器来捕获更新和删除。
我不认为你可以告诉 CDC 需要注意什么 DML,我认为让 CDC 记录所有这些插入然后删除它们是相当浪费的。这本身就很昂贵,并且它会导致的碎片也会导致您对捕获表运行的任何查询(您将有很多大部分为空的页面)以及工作统计信息必须不断做保持最新的统计数据。
您可以在捕获表上放置一个而不是插入触发器,它什么都不做,但我没有尝试这样做甚至查看它是否被允许,我当然不知道这会对疾控中心职能。可能值得进行一些调查,但即使这个 hack 确实有效,我的原始答案仍然有效:只需使用触发器。
如果空间是一个考虑因素,您始终可以分配 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)