概述
变更数据捕获用于捕获应用到 SQL Server 表中的插入、更新和删除活动,并以易于使用的关系格式提供这些变更的详细信息。变更数据捕获所使用的更改表中包含镜像所跟踪源表列结构的列,同时还包含了解所发生的变更所需的元数据。
对表开启了变更捕获之后,对该表的所有DML和DDL操作都会被记录,有助于跟踪表的变化。
测试环境: SQL SERVER 2008 R2,案例库AdventureWorks2008R2
目录
--开启cdc
USE [AdventureWorks]
EXECUTE sys.sp_cdc_enable_db
GO
---如果开启数据库捕获报错误:15517,使用下面的方法处理
--ALTER AUTHORIZATION ON DATABASE::[AdventureWorks] TO [sa]
---查看是否设置成功,1代表开启cd
SELECT is_cdc_enabled FROM SYS.databases WHERE name='AdventureWorks'
为当前数据库中指定的源表启用变更数据捕获。对表启用变更数据捕获时,应用于此表的每个数据操纵语言 (DML) 操作的记录都将写入事务日志中。变更数据捕获进程将从日志中检索此信息,并将其写入可通过使用一组函数访问的更改表中。
格式:
sys.sp_cdc_enable_table
---表所属的架构名
@source_schema = 'source_schema',
----表名
@source_name = 'source_name' ,
---是用于控制更改数据访问的数据库角色的名称。
@role_name ='role_name',
--是用于命名变更数据捕获对象的捕获实例的名称,这个名称在后面的存储过程和函数中需要经常用到。
@capture_instance = 'capture_instance' ,
---指示是否对此捕获实例启用净更改查询支持如果此表有主键,
--或者有已使用 @index_name 参数进行标识的唯一索引,则此参数的默认值为 1。否则,此参数默认为 0。
@supports_net_changes = supports_net_changes,
--用于唯一标识源表中的行的唯一索引的名称。index_name 为 sysname,
--并且可以为 NULL。如果指定,则 index_name 必须是源表的唯一有效索引。
--如果指定 index_name,则标识的索引列优先于任何定义的主键列,就像表的唯一行标识符一样。
@index_name ='index_name' ,
--需要对哪些列进行捕获。captured_column_list 的数据类型为 nvarchar(max),
--并且可以为 NULL。如果为 NULL,则所有列都将包括在更改表中。
@captured_column_list ='captured_column_list',
--是要用于为捕获实例创建的更改表的文件组。
@filegroup_name ='filegroup_name',
--指示是否可以对启用了变更数据捕获的表执行 ALTER TABLE 的 SWITCH PARTITION 命令。
--allow_partition_switch 为 bit,默认值为 1。
@partition_switch = 'partition_switch'
注意:
对表启用变更数据捕获时,将生成一个更改表以及一个或两个查询函数。更改表充当捕获进程从事务日志中提取的源表更改的存储库。查询函数则用于从更改表中提取数据。这些函数的名称按以下方式派生自 capture_instance 参数:
所有更改函数: cdc.fn_cdc_get_all_changes_ < capture_instance >
净更改函数: cdc.fn_cdc_get_net_changes_ < capture_instance >
1.如果源表是数据库中第一个要启用变更数据捕获的表,并且数据库不存在事务发布,则 sys.sp_cdc_enable_table 还将为数据库创建捕获和清理作业。
它将 sys.tables 目录视图中的 is_tracked_by_cdc 列设置为 1。
2.对表启用变更数据捕获时,SQL Server 代理不必正在运行。但是,只有当 SQL Server 代理正在运行时,捕获进程才会处理事务日志并将条目写入更改表。
USE AdventureWorks;
GO
EXEC sys.sp_cdc_enable_table
@source_schema = N'HumanResources'
, @source_name = N'Department'
, @role_name = N'cdc_admin'--增加的角色
, @capture_instance = N'HR_Department'--实例名
, @supports_net_changes = 1
, @index_name = N'AK_Department_Name'
, @captured_column_list = N'Name, GroupName'--跟踪的字段
, @filegroup_name = N'PRIMARY';
GO
---查询表是否启动跟踪,值为1标示已启动
SELECT is_tracked_by_cdc FROM SYS.tables WHERE name='Department'
---所有cdc有关的对象
SELECT * FROM SYS.all_objects WHERE name LIKE '%CDC%'OR SCHEMA_ID IN(SELECT SCHEMA_ID FROM SYS.schemas WHERE name='CDC')
ORDER BY TYPE
SELECT * FROM msdb.SYS.objects WHERE name='cdc_jobs'
---查询插入数据之前表中的内容
USE [AdventureWorks2008R2]
SELECT * FROM [HumanResources].[Department]
--1.插入一条记录
INSERT INTO [AdventureWorks2008R2].[HumanResources].[Department]([Name],[GroupName],[ModifiedDate])
VALUES('TEST','TEST',GETDATE())
GO
--更新一条记录
UPDATE [HumanResources].[Department]
SET GroupName='TEST1'
WHERE GroupName='TEST'
--增加一个字段
ALTER TABLE [HumanResources].[Department]
ADD Dcolumn INT
SELECT * FROM cdc.ddl_history---与DDL有关的操作记录
SELECT * FROM cdc.HR_Department_CT
/*
__$operation字段的值:
1 = 删除
2 = 插入
3 = 更新(旧值)
列数据中具有执行更新语句之前的行值。
4 = 更新(新值)
列数据中具有执行更新语句之后的行值。
*/
为每个在更改表中存在行的事务返回一行。该表用于在日志序列号 (LSN) 提交值和提交事务的时间之间建立映射。没有对应的更改表项的项也可以记录下来,以便表在变更活动少或者无变更活动期间将 LSN 处理的完成过程记录下来。
SELECT * FROM cdc.lsn_time_mapping
---查询当前作业配置
SELECT * FROM MSDB.dbo.cdc_jobs
--或者使用
USE AdventureWorks2008R2;
GO
EXEC sys.sp_cdc_help_jobs;
GO
1.sys.sp_cdc_add_job
在当前数据库中创建变更数据捕获清理或捕获作业
1.创建捕获作业
USE AdventureWorks2008R2;
GO
EXEC sys.sp_cdc_add_job
@job_type = N'capture';
GO
2.创建清理作业
---创建清理作业,作业连续运行,更改数据行将在更改表中保留2880分钟,清除时使用一条语句最多删除4000条记录
USE AdventureWorks2008R2;
GO
EXEC sys.sp_cdc_add_job
@job_type = N'cleanup'
,@start_job=1
,@retention=2880
,@threshold =4000
2.sys.sp_cdc_change_job
修改当前数据库中变更数据捕获清除或捕获作业的配置
--仅在使用 sp_cdc_stop_job 停止作业并使用 sp_cdc_start_job 重新启动该作业后,对该作业所做的更改才会生效
1.更改捕获作业
--将每个循环扫描最多处理的事务数更改为200,为了从日志中提取所有行而要执行的最大扫描循环50次
USE AdventureWorks2008R2;
GO
EXECUTE sys.sp_cdc_change_job
@job_type = N'capture',
@maxtrans = 200,
@maxscans = 50;
GO
2.更改清除作业,将记录保留时间更改为3440分钟
USE AdventureWorks2008R2;
GO
EXECUTE sys.sp_cdc_change_job
@job_type = N'cleanup',
@retention = 3440;
GO
3.sys.sp_cdc_cleanup_change_table
根据指定的 low_water_mark 值从当前数据库的更改表中删除行,重置更改表中的最小 __$start_lsn,并删除小于该值的数据.
将同时清除cdc.HR_Department_CT,cdc.lsn_time_mapping表的记录
USE AdventureWorks2008R2;
GO
EXEC sys.sp_cdc_cleanup_change_table
@capture_instance =N'HR_Department',
@low_water_mark=0x0000037D000000D30008,
@threshold=2000;
SELECT sys.fn_cdc_increment_lsn(sys.fn_cdc_get_max_lsn())
4.sys.sp_cdc_drop_job
从 msdb 中删除当前数据库的变更数据捕获清除或捕获作业。
--下例删除 AdventureWorks2008R2 数据库的清除作业和捕获作业
USE AdventureWorks2008R2;
GO
EXEC sys.sp_cdc_drop_job @job_type = N'cleanup';
USE AdventureWorks2008R2;
GO
EXEC sys.sp_cdc_drop_job @job_type = N'capture';
5.sys.sp_cdc_disable_db
对当前数据库禁用变更数据捕获
禁用当前对数据库中的所有表启用的变更数据捕获。与变更数据捕获相关的所有系统对象(如更改表、作业、存储过程和函数)都将被删除。sys.databases 目录视图中的数据库条目的 is_cdc_enabled 列设置为 0。
如果在禁用变更数据捕获时为数据库定义了很多捕获实例,则长时间运行事务可能导致 sys.sp_cdc_disable_db 的执行失败。通过在运行 sys.sp_cdc_disable_db 之前使用 sys.sp_cdc_disable_table 禁用单个捕获实例,可以避免此问题。
USE AdventureWorks2008R2;
GO
EXECUTE sys.sp_cdc_disable_db;
GO
6.sys.sp_cdc_disable_table
对当前数据库中指定的源表和捕获实例禁用变更数据捕获
删除与指定的源表和捕获实例相关联的变更数据捕获更改表和系统函数。它会删除任何与来自变更数据捕获系统表的指定捕获实例相关联的行,并将 sys.tables 目录视图中的表项的 is_tracked_by_cdc 列设置为 0。
---下例对 HumanResources.Department 表禁用了变更数据捕获
USE AdventureWorks2008R2;
GO
EXEC sys.sp_cdc_disable_table
@source_schema = N'HumanResources'
, @source_name = N'Department'
, @capture_instance = N'HR_Department' ---这里是定义的实例名称,在一开始创建捕获的时候创建的,这里也可以制定ALL(禁用表HumanResources.Department的所有捕获),
7.sys.sp_cdc_enable_db
对当前数据库启用变更数据捕获。必须先对数据库执行此过程,然后才能对该数据库中的任何表启用变更数据捕获。变更数据捕获可记录应用到所启用的表中的插入、更新和删除活动,同时采用易于使用的关系格式提供变更详细信息。此操作将为已修改的行捕获反映了所跟踪源表列结构的列信息,同时还捕获将更改应用到目标环境所需的元数据。
将创建以全数据库为作用域的变更数据捕获对象,包括元数据表和 DDL 触发器。它还会创建 cdc 架构和 cdc 数据库用户,并将 sys.databases 目录视图中的数据库条目的 is_cdc_enabled 列设置为 1。
USE AdventureWorks2008R2;
GO
EXECUTE sys.sp_cdc_enable_db;
GO
8.sys.sp_cdc_enable_table
--对需要进行跟踪的表启动CDC,sys.sp_cdc_enable_table
/*
为当前数据库中指定的源表启用变更数据捕获。对表启用变更数据捕获时,应用于此表的每个数据操纵语言 (DML) 操作的记录都将写入事务日志中。
变更数据捕获进程将从日志中检索此信息,并将其写入可通过使用一组函数访问的更改表中。
*/
sys.sp_cdc_enable_table
[ @source_schema = ] 'source_schema', ---表所属的架构名
[ @source_name = ] 'source_name' ,----表名
[ @role_name = ] 'role_name'---是用于控制更改数据访问的数据库角色的名称。
[,[ @capture_instance = ] 'capture_instance' ]--是用于命名特定于实例的变更数据捕获对象的捕获实例的名称
[,[ @supports_net_changes = ] supports_net_changes ]---指示是否对此捕获实例启用净更改查询支持
[,[ @index_name = ] 'index_name' ]--用于唯一标识源表中的行的唯一索引的名称。index_name 为 sysname,并且可以为 NULL。如果指定,则 index_name 必须是源表的唯一有效索引。如果指定 index_name,则标识的索引列优先于任何定义的主键列,就像表的唯一行标识符一样。
[,[ @captured_column_list = ] 'captured_column_list' ]--需要对哪些列进行捕获。captured_column_list 的数据类型为 nvarchar(max),并且可以为 NULL。如果为 NULL,则所有列都将包括在更改表中。
[,[ @filegroup_name = ] 'filegroup_name' ]--是要用于为捕获实例创建的更改表的文件组。
[,[ @partition_switch = ] 'partition_switch' ]--指示是否可以对启用了变更数据捕获的表执行 ALTER TABLE 的 SWITCH PARTITION 命令。allow_partition_switch 为 bit,默认值为 1。
9.sp_cdc_generate_wrapper_function
生成用于为 SQL Server 中可用的变更数据捕获查询函数创建包装函数的脚本
EXEC sys.sp_cdc_generate_wrapper_function
10. sys.sp_cdc_help_change_data_capture
返回当前数据库中为变更数据捕获启用的每个表的变更数据捕获配置。最多可为每个源表返回两行,为每个捕获实例返回一行。
---返回制定表的捕获信息
USE AdventureWorks2008R2;
GO
EXECUTE sys.sp_cdc_help_change_data_capture
@source_schema = N'HumanResources', --架构名
@source_name = N'Department';--表名
GO
--返回所有表的捕获信息
USE AdventureWorks2008R2;
GO
EXECUTE sys.sp_cdc_help_change_data_capture
11.sys.sp_cdc_get_captured_columns
返回指定捕获实例所跟踪的捕获源列的变更数据捕获元数据信息。
USE AdventureWorks2008R2;
GO
EXECUTE sys.sp_cdc_get_captured_columns
@capture_instance = N'HR_Department';
GO
12.sys.sp_cdc_get_ddl_history
返回自对指定的捕获实例启用变更数据捕获后与该捕获实例关联的数据定义语言 (DDL) 更改历史记录。
与查询表是一样的结果
SELECT * FROM cdc.ddl_history
USE Adventur