SQL Server 2008的Change Data Capture(变更数据捕获)

来源:互联网 发布:国家网络应急响应计划 编辑:程序博客网 时间:2024/05/18 17:23

在常见的企业数据平台管理中有一项任务是一直困扰SQL Server DBA们的,这就是对数据更新的监控。很多数据应用都需要捕获对业务数据表的更新。笔者见过几种解决方案:

1、在数据表中加入特殊的标志列;
2、通过在数据表上创建触发器;
3、通过第三方产品,例如Lumigent的Log Explorer。

其实第1种和第2中方案都不好,因为第1种方法需要在应用程序编码的时候尤为小心,如果有一段数据访问逻辑忘了更新标志位就会导致遗漏某些数据更新,而第2种方法对性能影响过于明显,因为触发器的性能开销是众所周知的。第3种方法其实属于一种叫做Log Audit的方案体系。因为SQL Server同其他关系型数据库一样,所有数据操作都会在日志中记录,因此通过分析日志就可以获得完整的数据操作历史。SQL Server其实早就有内部的API可供ISV开发者中Log Audit的方案,不过微软对这套API控制比较严格,只有签署了一堆协议的核心级合作伙伴才能了解这套API。

因此,现对业务数据更新的跟踪在SQL Server平台上一直是一件非常头疼的事情,用户需要在投入大量开发精力和投入额外采购成本之间做出选择。幸运的事,微软终于在SQL Server 2008中提供了一套半公开的Log Audit机制,就是我们所说的Change Data Capture,我们后面简称CDC。

CDC的工作原理

我们前面说过CDC是通过分析日志获得数据操作历史信息的,那么CDC的工作原理到底是怎么样的呢?下图可以非常贴切地说明这个功能的原理:

◆当DML提交到应用数据库时,SQL Server必须写入日志,并在缓存中更新数据,然后在检查点将内存中的数据刷回数据文件。
◆CDC的内部进程根据CDC的设置,在日志文件中提取更新历史信息,并将这些个更新信息写入对应的更新跟踪表。
◆DBA或开发人员通过调用CDC的函数来访问更新跟踪表,提取感兴趣的更新历史信息,并通过ETL应用程序更新数据仓库。
◆理论上面更新跟踪表事会无限制增长的,因此CDC内部有一个清理进程,在默认情况下更新跟踪信息在写入跟踪表三天后会被自动清理。

CDC的配置

由于CDC是一项比较高端的功能,因此只有在SQL Server 2008的企业版、开发版和评估版中才能找到CDC功能。

启用数据库级别的CDC

要启用CDC功能,首先需要一个sysadmin服务器角色的成员用户激活数据库级别的CDC。

USE testdb
GO
EXEC sys.sp_cdc_enable_db
GO

如果想知道一个数据库是否启用了CDC功能,可以通过查询sys.databases系统目录的is_cdc_enabled字段。当一个数据库启用CDC功能后,SQL Server会自动在这个数据库中创建cdc架构和cdc用户,所有CDC相关的数据表和用户函数都会存放在cdc架构下。

CDC功能启用后,SQL Server会首先在cdc架构下创建五张表用于记录一些CDC的原数据,分别是ddl_history,change_tables,captured_columns,index_columns和lsn_time_mapping。

数据库启用了CDC后,接下来我们就需要在数据表上启用CDC了(需db_owner角色或sysadmin的用户), 设置后,DBA可以查询sys.tables系统目录的is_tracked_by_cdc字段

USE testdb
GO

EXEC sys.sp_cdc_enable_table
@source_schema = N'dbo',
@source_name   = N't_test_orders',  --源表名,  即将生成的"更改表"名为:  cdc.dbo_t_test_orders_CT,位于同一db下.
@role_name     = NULL,                        -- 需显示指定是否要限定"更改表"的访问角色.
@filegroup_name = N'PRIMARY',        --指定"更改表"存放的文件组,以减少对"源表"文件组的io影响
@supports_net_changes = 1               --启用净更新, "源表"必须有主键或唯一分键。查询net_changes时会merge掉中间的更新,比较耗性能
--忽略了一个参数就是@captured_column_list,这个参数可以对表中特定的某些字段启用更新跟踪。

GO

"更改表"cdc.dbo_t_test_ordrs_CT,增加了_$start_lsn,_$end_lsn,_$seqval,_$operation和_$update_mask五个新的字段. _$operation字段是代表DML操作类型,1是delete,2是insert,3是update的旧值,4是update的新值。
$update_mask字段是表示一个字段列表的掩码,那些在DML操作中被更新了的字段位为1,而没有更新的字段位为0。如更新第1列就是0x01, 更新第1,2列就是0x11.

如果"源表"新增加了列需要跟踪,需要先禁用,再启用跟踪.

USE testdb
GO
EXEC sys.sp_cdc_disable_table
@source_schema = N'dbo',
@source_name   = N't_test_orders',
@capture_instance = N'dbo_t_test_orders'       --注意不是更新表名"dbo_t_test_orders_CT", 少了CT
GO

查询和操作"更改表": 

sys.fn_cdc_get_min_lsn,  sys.fn_cdc_get_max_lsn(),  cdc.lsn_time_mapping,  sys.fn_cdc_map_time_to_lsn()cdc.fn_cdc_get_all_changes*, cdc.fn_cdc_get_net_changes*

DECLARE @from_lsn binary(10), @to_lsn binary(10)
SET @from_lsn = sys.fn_cdc_get_min_lsn('dbo_t_test_orders')
SET @to_lsn   = sys.fn_cdc_get_max_lsn()
SELECT * FROM cdc.fn_cdc_get_all_changes_dbo_t_test_orders(@from_lsn, @to_lsn, N'all')

CDC管理和监控

监视变更数据捕获进程: select * from sys.dm_cdc_log_scan_sessions

变更数据捕获日志扫描会话期间遇到的每个错误: sys.dm_cdc_errors
捕捉作业:sp_MScdc_capture_job,   清除作业sp_MScdc_cleanup_job

对部署CDC的建议

◆CDC激活会显著增加日志文件的读操作。
◆CDC激活后更新跟踪表会产生额外的写入,并消耗存储空间。
◆CDC激活后,原数据表的聚簇索引尺寸会影响到CDC产生的IO数据量,而原始数据表上的非聚簇索引则不会。
◆CDC激活后,被选定进行更新跟踪的列键值属性同样会影响到CDC产生的IO数据量和存储空间。

参考网址:http://www.chinaz.com/program/2008/0604/30598_4.shtml 

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 鹦鹉鱼身上有小白点怎么办 鹦鹉鱼身上烂了怎么办 红鹦鹉鱼变黑了怎么办 唱美声总夹嗓子怎么办 发财树树干出褶怎么办 月季花夏天换盆出现黄叶怎么办 刚种的月季枯了怎么办 新买的月季黄叶了怎么办 月季花叶孑轰发黄怎么办? 新种的月季苗弱怎么办? 月季换盆后浇透水叶子黄了怎么办 肉肉移栽后浇透水怎么办 月季花扦插的没长根发芽了怎么办 君子兰发的小苗怎么办 蔷薇光长枝条不开花怎么办 牡丹发芽又干了怎么办 擦皮炎平后皮肤变黑怎么办 误喝发霉的咖啡渣怎么办 狗吃了速溶咖啡怎么办 咖啡机放豆的地方进水怎么办 干吃咖啡粉上瘾怎么办 去良友花艺住宿怎么办 充气娃娃放了气怎么办 煮杜鹃根没有锅怎么办 淘宝店卖鲜花被买家拒收货怎么办 执业医师电子注册忘记密码怎么办 怀孕吃了油炸的怎么办 百合长得太高怎么办 百合的杆没了怎么办 百合花长得太细怎么办 沙漠玫瑰的花苞打不开怎么办 鲜切花 较小的花苞怎么办 大棚玫瑰苗水大涝的不长怎么办 鲜花买回来蔫了怎么办 喝玫瑰醋上火了怎么办 插在花泥上的花怎么办 插的花蔫了怎么办 紫睡莲的茎软了怎么办 家养的荷花烂叶怎么办 家养的荷花叶老是枯萎怎么办 新买的绣球蔫了怎么办