1. 什么是变更数据捕获 (
CDC
)变更数据捕获 (
CDC
) 使用SQL Server
代理来记录应用于表的插入、更新和删除活动。 这样,就可以按易于使用的关系格式提供这些更改的详细信息。将为修改的行捕获列信息以及将更改应用于目标环境所需的元数据,并将其存储在镜像所跟踪源表的列结构的更改表中。
系统提供了一些表值函数,以便使用者可以系统地访问更改数据。此技术针对的数据使用者的一个典型示例是提取、转换和加载 (ETL
) 应用程序。ETL
应用程序以增量方式将SQL Server
源表中的更改数据加载到数据仓库或数据市场。 虽然数据仓库中的源表的表示形式必须反映源表中的更改,但刷新源副本的端到端技术并不适用。 相反,您需要一种具有特定结构的可靠更改数据流,以便使用者可以将其应用于不同的目标数据表示形式。SQL Server
变更数据捕获就提供了这一技术。2.变更数据捕获的主体数据流
变更数据捕获的更改数据源为SQL Server
事务日志。 在将插入、更新和删除应用于跟踪的源表时,将会在日志中添加说明这些更改的项。 日志用作捕获进程的输入来源。它会读取日志,并在跟踪的表的关联更改表中添加有关更改的信息。 系统将提供一些函数,以枚举在更改表中指定范围内发生的更改,并以筛选的结果集的形式返回该值。 通常,应用程序进程使用筛选的结果集在某种外部环境中更新源表示形式。3.开启CDC的必要条件
3.1 SQL server 2008 以上的企业版、开发版和评估版中可用
3.2 需要开启代理服务(作业)
3.3 CDC需要业务库之外的额外的磁盘空间,保存日志文件
3.4 表必须要有主键或者是唯一索引
已经设置数据库DB_Student
的表tb_teacher
的列teaid
为主键。4.检查和开启数据库的
CDC
服务4.1 查询数据库的
CDC
服务状态
select is_cdc_enabled from sys.databases where name='DB_Student'
查询结果为0,表示尚未开启数据库
DB_Student
的CDC
服务。4.2 开启数据库级别的
CDC
功能
ALTER AUTHORIZATION ON DATABASE::[DB_Student] TO [sa];
if exists(select 1 from sys.databases where name='DB_Student' and is_cdc_enabled=0)
begin
exec sys.sp_cdc_enable_db
end
;
select is_cdc_enabled from sys.databases where name='DB_Student';
结果为0,表示已经开启数据库
DB_Student
的CDC
服务5. 添加CDC专用的文件组和文件
SELECT name, physical_name FROM sys.master_files WHERE database_id = DB_ID('DB_Student');
ALTER DATABASE DB_Student ADD FILEGROUP CDC1;
ALTER DATABASE DB_Student
ADD FILE
(
NAME= 'DB_Student_CDC1',
FILENAME = 'D:\DATA\DB_Student_CDC1.ndf'
)
TO FILEGROUP CDC1;
6. 操作开启表级别
CDC
(注意:表中必须有主键或者唯一索引)
SELECT name,is_tracked_by_cdc FROM sys.tables WHERE is_tracked_by_cdc = 0;
IF EXISTS(SELECT 1 FROM sys.tables WHERE name='tb_teacher' AND is_tracked_by_cdc = 0)
BEGIN
EXEC sys.sp_cdc_enable_table
@source_schema = 'dbo',
@source_name = 'tb_teacher',
@capture_instance = NULL,
@supports_net_changes = 1,
@role_name = NULL,
@index_name = NULL,
@captured_column_list = NULL,
@filegroup_name = 'CDC1'
END;
DECLARE @tableName nvarchar(36)
DECLARE My_Cursor CURSOR
FOR (SELECT 'new_srv_workorderBase' name
union select 'tablename1'
union select 'tablename2'
union select 'tablename3'
)
OPEN My_Cursor;
FETCH NEXT FROM My_Cursor INTO @tableName;
WHILE @@FETCH_STATUS = 0
BEGIN
EXEC sys.sp_cdc_enable_table
@source_schema = 'dbo',
@source_name = @tableName,
@capture_instance = NULL,
@supports_net_changes = 1,
@role_name = NULL,
@index_name = NULL,
@captured_column_list = NULL,
@filegroup_name = 'CDC1'
FETCH NEXT FROM My_Cursor INTO @tableName;
END
CLOSE My_Cursor;
DEALLOCATE My_Cursor;
SELECT name,is_tracked_by_cdc FROM sys.tables WHERE is_tracked_by_cdc = 1 ORDER BY NAME;
7.验证是否成功开启
CDC
7.1 查看
tb_teacher
表开启CDC
状态结果为1,表示已经成功CDC
服务。
select name, is_tracked_by_cdc from sys.tables where object_id = OBJECT_ID('DB_Student')
7.2 成功开启数据库
DB_Student
的CDC
服务后,在SQL Server
代理—作业处有cdc.DB_Student_capture
和cdc.DB_Student_cleanup
的作业7.3 成功开启后
CDC
服务后,在数据库“DB_Student
—可编程序—函数—表值函数”会有如下函数生成。
cdc.fn_cdc_get_all_changes_dbo_tb_teacher
:针对在指定日志序列号 (LSN
) 范围内应用到源表的每项更改均返回一行。如果源行在该间隔内有多项更改,则每项更改都会表示在返回的结果集中。
cdc.fn_cdc_get_net_changes_dbo_tb_teacher
:针对指定LSN
范围内每个已更改的源行返回一个净更改行。也就是说,如果在LSN
范围内源行具有多项更改,则该函数将返回反映该行最终内容的单一行。
sys.fn_cdc_map_time_to_lsn
:为指定的时间返回cdc.lsn_time_mapping
系统表中start_lsn
列中的日志序列号 (LSN
) 值。可以使用此函数系统地将日期时间范围映射到基于LSN
的范围,以供变更数据捕获枚举函数cdc.fn_cdc_get_all_changes_
和cdc.fn_cdc_get_net_changes_
返回此范围内的数据更改。7.4 成功开启后CDC服务后,在数据库“DB_Student—表—系统表”会有如下表生成。
cdc.change_tables
:表开启cdc
后会插入一条数据到这张表中,记录表一些基本信息
cdc.captured_columns
:开启cdc
后的表,会记录它们的字段信息到这张表中
cdc.dbo_VW_GHZDK_CT
:记录VW_GHZDK
表中所有变更的数据,字段“__$operation
”为“1”代表删除,“2”代表插入,“3”执行更新操作前的值,“4”执行更新操作后的值。字段“__$start_lsn
”由于更改是来源于数据库的事务日志,所以这里会保存其事务日志的开始序列号(LSN
)。8. 验证
CDC
实现数据变更捕获的功能8.1查询系统表
cdc.dbo_tb_teacher_CT
SELECT * FROM cdc.dbo_tb_teacher_CT
由查询结果可以看到系统表
cdc.dbo_tb_teacher_CT
没有任何记录。因为表刚刚创建,没有对原表dbo.tb_teacher
做任何增删改操作。8.2 向
tb_teacher
表插入记录和再次查询cdc.dbo_tb_teacher_CT
在对表tb_teacher
插入数据之后,对系统表cdc.dbo_tb_teacher_CT
进行查询操作,此时可以看到多了一条记录。结合7.4可以知道向数据表tb_teacher
各插入和更新一条数据记录。