开启 SQL Server 的 Change Data Capture, 并验证 CDC 开启后的效果

1. 什么是变更数据捕获 (CDC)

变更数据捕获 (CDC) 使用 SQL Server 代理来记录应用于表的插入、更新和删除活动。 这样,就可以按易于使用的关系格式提供这些更改的详细信息。将为修改的行捕获列信息以及将更改应用于目标环境所需的元数据,并将其存储在镜像所跟踪源表的列结构的更改表中。

系统提供了一些表值函数,以便使用者可以系统地访问更改数据。此技术针对的数据使用者的一个典型示例是提取、转换和加载 (ETL) 应用程序。ETL 应用程序以增量方式将 SQL Server 源表中的更改数据加载到数据仓库或数据市场。 虽然数据仓库中的源表的表示形式必须反映源表中的更改,但刷新源副本的端到端技术并不适用。 相反,您需要一种具有特定结构的可靠更改数据流,以便使用者可以将其应用于不同的目标数据表示形式。 SQL Server 变更数据捕获就提供了这一技术。

2.变更数据捕获的主体数据流

在这里插入图片描述
变更数据捕获的更改数据源为 SQL Server 事务日志。 在将插入、更新和删除应用于跟踪的源表时,将会在日志中添加说明这些更改的项。 日志用作捕获进程的输入来源。它会读取日志,并在跟踪的表的关联更改表中添加有关更改的信息。 系统将提供一些函数,以枚举在更改表中指定范围内发生的更改,并以筛选的结果集的形式返回该值。 通常,应用程序进程使用筛选的结果集在某种外部环境中更新源表示形式。

3.开启CDC的必要条件

3.1 SQL server 2008 以上的企业版、开发版和评估版中可用

在这里插入图片描述
版本检查:已安装的SQL Server版本为2019开发版

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_StudentCDC服务。

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_StudentCDC服务

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_StudentCDC服务后,在SQL Server代理—作业处有cdc.DB_Student_capturecdc.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_<capture_instance>cdc.fn_cdc_get_net_changes_<capture_instance> 返回此范围内的数据更改。

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各插入和更新一条数据记录。

猜你喜欢

转载自blog.csdn.net/weixin_51571728/article/details/126535938