介绍:SQL Server 2008变更数据捕获

SQL Server 2008的CDC函数读取激活了CDC的每个表所关联的事务日志来记录系统表中的变更。它将这些文件写到同一个数据库的系统表中,这些系统表是可以通过直接查询或系统函数来访问的。

让我们看些示例代码并看看每一步有什么改变。

使用示例代码来跟踪可变部分

首先,我们从一个全新的数据库开始。要跟踪这些变更,打开对象浏览器并展开这些文件夹:

· Databases

· SQLServer Agent | Jobs

· (数据库创建之后)Security | Roles | Database Roles

· (数据库创建之后)Programmability | Stored Procedures | System Stored Procedures

· (数据库创建之后)Programmability | Functions | Table-valued Functions

创建数据库

CREATE DATABASE TestCdc

这为我们创建了新数据库,但是没有新作业。展开Tables文件夹和System Tables文件夹。现在是空的。

在数据库TestCdc上激活变更数据捕获

USE TestCdc

-- Turn on Change Data Capture at database level

EXEC sys.sp_cdc_enable_db

这个步骤需要一些时间。现在刷新System Tables文件夹。现在它下面有6个系统表:

· cdc.captured_columns

· cdc.change_tables

· cdc.ddl_history

· cdc.index_columns

· cdc.lsn_time_mapping

· dbo.systranschemas

注意,其中的5个是“cdc” schema 部分的。

在sys.all_objects表中还有四个新的看起来很奇怪的“SQL inline table-valued function”登录:

· fn_cdc_get_all_changes_◦...◦

· fn_cdc_get_all_changes_...

· fn_cdc_get_net_changes_◦...◦

· fn_cdc_get_net_changes_...

(我使用了非比例字体,用“◦”来标记空格,使得很清楚地看到在这些名称中有嵌入的空格。)

下面是会返回这些函数的查询:

SELECT [name] FROM sys.all_objects WHERE [name] LIKE '%...%'

还有更多的新存储过程

· sp_batchinsert_lsn_time_mapping

· sp_ins_dummy_lsn_time_mapping

· sp_ins_instance_enabling_lsn_time_mapping

· sp_ins_lsn_time_mapping

现在还没有新的作业或角色。

创建新的Schema和用户表

CREATE SCHEMA MySchema

CREATE TABLE MySchema.Person (

PersonID int IDENTITY PRIMARY KEY,

FirstName varchar(32) NOT NULL,

LastName varchar(32) NOT NULL,

UpdateCt int NOT NULL DEFAULT 0

)

上面的代码创建了一个新的用户表,但是这个表还没有激活CDC。

这个步骤不影响我们所跟踪的函数/存储过程/角色列表。

为新的用户表激活CDC

EXEC sys.sp_cdc_enable_table

@source_schema = N'MySchema',

@source_name = N'Person',

@role_name = N'ChangeDataAccessRole',

@supports_net_changes = 1

这会为新的用户表激活CDC。刷新上面所列的文件夹。我们现在有了

· 一个新的系统表(cdc.MySchema_Person_CT)

· 两个新的作业(cdc.TestCdc_capture和cdc.TestCdc_cleanup)

· 一个新的数据库角色(ChangeDataAccessRole)

· 两个新的表值型函数

o fn_cdc_get_all_changes_MySchema_Person

o fn_cdc_get_net_changes_MySchema_Person

· 三个新的存储过程:

o sp_batchinsert_389576426

o sp_insdel_389576426

o sp_upd_389576426

你可以获得这些存储过程(sp_helptext 'cdc.sp_batchinsert_389576426' 【你的数字可能不一样】)的文本。很明显这个存储过程被生成了,而且是专用于这个用户表的。

如果你为第二个表激活了CDC,那么你将获得另一组的sp_batchinsert_n、sp_insdel_n和sp_upd_n存储过程。

系统表cdc.MySchema_Person_CT

这个表具有以下字段:

· __$start_lsn

· __$end_lsn

· __$seqval

· __$operation

· __$update_mask

· PersonID

· FirstName

· LastName

· UpdateCt

作业cdc.TestCdc_capture

当你研究这个捕捉作业时,你会发现它是很有趣的。从sysjobs,我们可以看出这个作业是属于sa的,是在“REPL-LogReader”分类中,并有一个“CDC Log Scan Job”的描述。

从sysjobsteps,我们看到它有两个步骤:

读过这些细节之后,接下来有两个步骤,但是我们将保留第二个,直到我们插入了一些数据之后再执行

sp_helptext N'sys.sp_MScdc_capture_job'

SELECT * FROM sys.dm_cdc_log_scan_sessions

存储过程Psys.sp_MScdc_capture_job和sys.sp_cdc_scan

sys.sp_MScdc_capture_job是开始整个CDC过程的存储过程。它首先进行一些安全检查,然后调用sys.sp_cdc_scan,这将进行实质的工作。sys.sp_cdc_scan执行变更数据捕获日志扫描操作。

默认情况下,sys.sp_cdc_scan在每个循环间进行五秒钟的延迟。在每个常规的循环中,它调用sp_replcmds。(这是个复制存储过程。使用默认(1)调用这个存储过程会返回等待分配的下一个事务。在这个存储过程中,默认@maxtrans是500。)

最后,它从sys.dm_cdc_log_scan_sessions读取来准备调用sp_sqlagent_log_jobhistory,从而记录作业历史信息。

数据库角色ChangeDataAccessRole

如果你打开新的ChangeDataAccessRole角色的属性窗口,那么你会看到这个角色属于“cdc”,并且具有对上面所列的两个表值型函数的SELECT权限,除此之外没有其它权限。

总结

研究这些细节使我们了解了Server 2008的CDC是怎样执行的。

posted on 2013-04-27 09:57  代岳强  阅读(324)  评论(0编辑  收藏  举报