SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑

关键词:CDC,数据库审计

详细参考:微软官网大神总结

原文:http://www.cnblogs.com/chenxizhang/archive/2011/08/10/2133408.html

SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑

CDC(Change Data Capture:变更数据捕获)这个功能是SQL Server 2008企业版的功能,它提供了一种新的机制,对表格数据的更新进行跟踪,在数据仓库的建设过程中,通过这种技术,可以简化从业务数据库导入数据的复杂度。

之前我有过两篇文章介绍,最近因为又在和有关客户介绍这方面的应用。发现之前的例子不是那么完整和清楚,特此再整理一篇出来,给大家参考

一、什么是CDC?

变更数据捕获(Change Data Capture ,简称 CDC)记录 SQL Server 表的插入、更新和删除活动。SQLServer的操作会写日志,这也是CDC捕获数据的来源。

开启cdc的源表在插入、更新和删除活动时会插入数据到日志表中。cdc通过捕获进程将变更数据捕获到变更表中,通过cdc提供的查询函数,我们可以捕获这部分数据。

二、开启CDC

2.1、开启CDC的必要条件

  • sqlserver 2008 以上版本

  • 需要开启代理服务(作业)

  • 磁盘要有足够的空间,保存日志文件

  • 表必须要有主键或者是唯一索引

2.2、开启数据库CDC

1、 在需要开启cdc的数据库上执行脚本如下:

  1. if exists(select 1 from sys.databases where name='db_name' and is_cdc_enabled=0)
  2. begin
  3. exec sys.sp_cdc_enable_db
  4. end

2、查询数据库的cdc开启状态

  1. select is_cdc_enabled from sys.databases where name='db_name'

查询结果为“1”,表示开启成功。

2.3、开启表CDC

*注意:表中必须有主键或者唯一索引

1、添加次要数据文件组及文件

数据库右键“属性” >> “文件组”>> ”添加”

“文件” >> “添加”

2、执行以下脚本,开启表cdc

  1. --CDC是数据库文件组的名称
  2. IF EXISTS(SELECT 1 FROM sys.tables WHERE name='table_name' AND is_tracked_by_cdc = 0)
  3. BEGIN
  4. EXEC sys.sp_cdc_enable_table
  5. @source_schema = 'dbo', -- source_schema
  6. @source_name = 'table_name', -- table_name
  7. @capture_instance = NULL, -- capture_instance
  8. @supports_net_changes = 1, -- supports_net_changes
  9. @role_name = NULL, -- role_name
  10. @index_name = NULL, -- index_name
  11. @captured_column_list = NULL, -- captured_column_list
  12. @filegroup_name = 'CDC' -- filegroup_name
  13. END

3、查看表cdc开启状态

  1. SELECT is_tracked_by_cdc FROM sys.tables WHERE name='table_name'

查询结果为“1”,表示开启成功。

三、使用CDC

开启cdc后会在数据库中生成以下文件,开启数据库GY_DB,开启表VW_GHZDK

下面我们会对部分表和函数进行说明

系统表:

cdc.change_tables:表开启cdc后会插入一条数据到这张表中,记录表一些基本信息

cdc.captured_columns:开启cdc后的表,会记录它们的字段信息到这张表中

cdc.VW_GHZDK_CT(cdc.表名_CT):记录VW_GHZDK表中所有变更的数据,

字段“__$operation”为“1”代表删除,“2”代表插入,“3”执行更新操作前的值,“4”执行更新操作后的值。字段“__$start_lsn”由于更改是来源于数据库的事务日志,所以这里会保存其事务日志的开始序列号(LSN)

函数:

cdc.fn_cdc_get_all_changes_dbo_VW_GHZDK:针对在指定日志序列号 (LSN) 范围内应用到源表的每项更改均返回一行。如果源行在该间隔内有多项更改,则每项更改都会表示在返回的结果集中

cdc.fn_cdc_get_net_changes_dbo_VW_GHZDK:针对指定 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> 返回此范围内的数据更改。

四、最佳实践:案例演示

-----------------------------------

1. 准备一个数据库,里面准备一个表,Orders

  

2. 启用数据库级别的CDC选项

  1. --在数据库级别启用CDC功能
  2. EXEC sys.sp_cdc_enable_db

这个命令执行完之后,会在系统表里面添加6个表格

    

3.在需要做数据捕获的表上面启用CDC选项

  1. EXEC sys.sp_cdc_enable_table
  2.   @source_schema='dbo',
  3.   @source_name='Orders',
  4.   @capture_instance='Orders',
  5.   @supports_net_changes=0,
  6.   @role_name=null

【备注】关于这个存储过程的具体用法和有关参数的含义,请参考

http://msdn.microsoft.com/en-us/library/bb522475.aspx

执行之后,会有如下的输出消息

这个提示的意思是说,要启动SQL Server Agent。因为CDC功能是要通过一个两个作业来自动化完成的

  

与此同时,执行上面的命令还将在系统表中添加一个表格

  

还会添加一个函数

  

4.插入或者更新数据测试CDC功能

  1. --插入或者更新数据测试CDC功能
  2. INSERT Orders(CustomerID) VALUES('Microsoft');
  3. INSERT Orders(CustomerID) VALUES('Google');
  4.  
  5. UPDATE Orders SET CustomerID='Yahoo' WHERE OrderID=1
  6. DELETE FROM Orders WHERE OrderID=2

这个范例插入两行数据,紧接着又对第一行更新,然后还删除了第二行,所以最终只有一行数据

  

那么,我们来看看CDC做了什么事情呢?

  1. SELECT * FROM cdc.Orders_CT

  

我们可以来解释一下上面结果的含义

__$operation=2的情况,表示新增

__$operation=3或者4,表示更新,3表示旧值,4表示新值

__$operation=1的情况,表示删除

很好理解,不是吗?

但是,我们一般都是需要按照时间范围进行检索,对吧,所以,需要使用下面的语法进行查询

  1. --按照时间范围查询CDC结果
  2. DECLARE @from_lsn BINARY(10),@end_lsn BINARY(10)
  3. DECLARE @start_time DATETIME = '2011-8-10 00:00:00'
  4. DECLARE @end_time DATETIME ='2011-8-11 00:00:00'
  5. SELECT @from_lsn=sys.fn_cdc_map_time_to_lsn('smallest greater than or equal',@start_time)
  6. SELECT @end_lsn=sys.fn_cdc_map_time_to_lsn(' largest less than or equal',@end_time)
  7. SELECT * FROM cdc.fn_cdc_get_all_changes_Orders(@from_lsn,@end_lsn,'all')

关于sys.fn_cdc_map_time_to_lsn这个函数,请参考

http://msdn.microsoft.com/en-us/library/bb500137.aspx

查询的结果如下

如果需要包含更新操作的旧值,则可以以下的语法

  1. DECLARE @from_lsn BINARY(10),@end_lsn BINARY(10)
  2. DECLARE @start_time DATETIME = '2011-8-10 00:00:00'
  3. DECLARE @end_time DATETIME ='2011-8-11 00:00:00'
  4. SELECT @from_lsn=sys.fn_cdc_map_time_to_lsn('smallest greater than or equal',@start_time)
  5. SELECT @end_lsn=sys.fn_cdc_map_time_to_lsn(' largest less than or equal',@end_time)
  6. SELECT * FROM cdc.fn_cdc_get_all_changes_Orders(@from_lsn,@end_lsn,'all update old')

  

通常,为了方便起见,我们会将这个查询定义为一个存储过程,如下

  1. --定义存储过程来进行查询
  2. CREATE PROC GetOrdersCDCResult(@start_time DATETIME,@end_time DATETIME)
  3. AS
  4. BEGIN
  5. DECLARE @from_lsn BINARY(10),@end_lsn BINARY(10)
  6. SELECT @from_lsn=sys.fn_cdc_map_time_to_lsn('smallest greater than or equal',@start_time)
  7. SELECT @end_lsn=sys.fn_cdc_map_time_to_lsn(' largest less than or equal',@end_time)
  8. SELECT * FROM cdc.fn_cdc_get_all_changes_Orders(@from_lsn,@end_lsn,'all')
  9. END

然后,每次需要用的时候,就直接调用即可

  1. --执行存储过程
  2. EXEC GetOrdersCDCResult '2011-8-10','2011-8-11'

5.结合SSIS实现事实表的增量更新

下面展示了一个SSIS 包的设计,这里面读取CDC的数据,先进行一些查找,然后按照__$operation的值拆分成为三个操作,分别进行插入,更新和删除,这样就可以实现对事实表的增量更新

  

本文所有的代码如下

  1. USE SampleDatabase
  2. GO
  3.  
  4. --在数据库级别启用CDC功能
  5. EXEC sys.sp_cdc_enable_db
  6.  
  7. --在需要做数据捕获的表格上面启用CDC功能
  8. EXEC sys.sp_cdc_enable_table
    @source_schema='dbo',
    @source_name='Orders',
    @capture_instance='Orders',
    @supports_net_changes=0,
    @role_name=null
  9.  
  10. --插入或者更新数据测试CDC功能
  11. INSERT Orders(CustomerID) VALUES('Microsoft');
  12. INSERT Orders(CustomerID) VALUES('Google');
  13.  
  14. UPDATE Orders SET CustomerID='Yahoo' WHERE OrderID=1
  15. DELETE FROM Orders WHERE OrderID=2
  16.  
  17. --查询CDC的结果
  18. SELECT * FROM cdc.Orders_CT
  19.  
  20. --按照时间范围查询CDC结果
  21. DECLARE @from_lsn BINARY(10),@end_lsn BINARY(10)
  22. DECLARE @start_time DATETIME = '2011-8-10 00:00:00'
  23. DECLARE @end_time DATETIME ='2011-8-11 00:00:00'
  24. SELECT @from_lsn=sys.fn_cdc_map_time_to_lsn('smallest greater than or equal',@start_time)
  25. SELECT @end_lsn=sys.fn_cdc_map_time_to_lsn(' largest less than or equal',@end_time)
  26. SELECT * FROM cdc.fn_cdc_get_all_changes_Orders(@from_lsn,@end_lsn,'all')
  27.  
  28. --定义存储过程来进行查询
  29. CREATE PROC GetOrdersCDCResult(@start_time DATETIME,@end_time DATETIME)
  30. AS
  31. BEGIN
  32. DECLARE @from_lsn BINARY(10),@end_lsn BINARY(10)
  33. SELECT @from_lsn=sys.fn_cdc_map_time_to_lsn('smallest greater than or equal',@start_time)
  34. SELECT @end_lsn=sys.fn_cdc_map_time_to_lsn(' largest less than or equal',@end_time)
  35. SELECT * FROM cdc.fn_cdc_get_all_changes_Orders(@from_lsn,@end_lsn,'all')
  36. END
  37.  
  38. --执行存储过程
  39. EXEC GetOrdersCDCResult '2011-8-10','2011-8-11'

SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑的更多相关文章

  1. SQL Server 2008中新增的 1.变更数据捕获(CDC) 和 2.更改跟踪

    概述 1.变更数据捕获(CDC)        每一次的数据操作都会记录下来 2.更改跟踪       只会记录最新一条记录   以上两种的区别:         http://blog.csdn.n ...

  2. SQL Server 2008中新增的变更数据捕获(CDC)和更改跟踪

    来源:http://www.cnblogs.com/downmoon/archive/2012/04/10/2439462.html  本文主要介绍SQL Server中记录数据变更的四个方法:触发器 ...

  3. SQL Server 2008中的数据压缩

    SQL Server 2008中引入了数据压缩的功能,允许在表.索引和分区中执行数据压缩.这样不仅可以大大节省磁盘的占用空间,还允许将更多数据页装入内存中,从而降低磁 盘IO,提升查询的性能.当然,凡 ...

  4. SQL Server 2008中数据压缩

    SQL Server 2008中引入了数据压缩的功能,允许在表.索引和分区中执行数据压缩.这样不仅可以大大节省磁盘的占用空间,还允许将更多数据页装入内存中,从而降低磁盘IO,提升查询的性能.当然,凡事 ...

  5. SQL点滴15—在SQL Server 2008中调用C#程序

    原文:SQL点滴15-在SQL Server 2008中调用C#程序 T-SQL的在执行普通的查询的时候是很高效的,但是在执行循环,判断这样的语句的时候效率就不那么的高了.这时可以借助CLR了,我们可 ...

  6. 在SQL Server 2008中调用.net,dll

    原文:在SQL Server 2008中调用.net,dll T-SQL的在执行普通的查询的时候是很高效的,但是在执行循环,判断这样的语句的时候效率就不那么的高了.这时可以借助CLR了,我们可以在SQ ...

  7. SQL SERVER 2008中使用VARBINARY(MAX)进行图像存取的实现方法

          在数据库应用项目开发中,经常会使用一些二进制的图像数据,存储和读取显示图像数据主要采用的是路径链接法和内存流法.路径链接法是将图像文件保存在固定的路径下,数据库中只存储图像文件的路径和名称 ...

  8. SQL Server 2008中增强的"汇总"技巧

    本文转载:http://www.cnblogs.com/downmoon/archive/2012/04/06/2433988.html SQL Server 2008中的Pivot和UnPivot: ...

  9. 利用Ring Buffer在SQL Server 2008中进行连接故障排除

    原文:利用Ring Buffer在SQL Server 2008中进行连接故障排除 出自:http://blogs.msdn.com/b/apgcdsd/archive/2011/11/21/ring ...

随机推荐

  1. ANTLR v4 专业术语集

    记录<The Definitive ANTLR 4 Reference>中出现的专业术语: grammar 文法,一种形式化(formal)的语言描述. syntax 语法 phrase ...

  2. Android 开发笔记

    11.android使用全局变量 定义Data类继承Application 在manifest.xml中声明 http://blog.csdn.net/feiyangxiaomi/article/de ...

  3. 关于在最新的 Visual Studio 2017 版本中使用 Web Deploy 遇到的 SSL 连接错误

    错误信息: 无法完成向远程代理 URL 发送请求.请求被中止: 未能创建 SSL/TLS 安全通道. 原因分析: 最新版本的 Visual Studio 中,已经抛弃了 https 协议中旧版 SSL ...

  4. 基于Python37配置图片文字识别

    以管理员权限打开cmd控制台. 1.如何安装PIL 输入下面命令:pip install Pillow 参考:https://www.cnblogs.com/mrgavin/p/8177841.htm ...

  5. Fluent动网格【11】:弹簧光顺

    动网格除了前面讲了很多的关于运动指定之外,另一个重要主题则为网格的更新. 在部件运动之后,不可避免的会造成网格形状的变化,如若不对网格加以控制,在持续运动的过程中,则可能造成网格极度变形.歪曲率过大, ...

  6. ss搭建

    aliyun ecs ,hongkong , t5 , 1M, 1.卸载阿里云盾监控 wget http://update.aegis.aliyun.com/download/uninstall.sh ...

  7. VS2013-2017 舒服的字体设置和背景色

    使用字体:Fixedsys Excelsior 3.01 1.如果没有安装字体的话,首先下载字体:http://www.fixedsysexcelsior.com/ 2.安装字体:控制面板 -> ...

  8. Cookie详解整理

    1.Cookie的诞生 由于HTTP协议是无状态的,而服务器端的业务必须是要有状态的.Cookie诞生的最初目的是为了存储web中的状态信息,以方便服务器端使用.比如判断用户是否是第一次访问网站.目前 ...

  9. greenplum 安装笔记

    折腾两天了,终于把greenplum装成功了.记录下遇到的问题. 环境变量一点要配置准确. greenplum安装,按照这里一步步走: http://www.cnblogs.com/liuyungao ...

  10. [原][openstack-pike][compute node][issue-1]openstack-nova-compute.service holdoff time over, scheduling restart.

    在安装pike  compute node节点的时候遇到启动nova-compute失败,问题如下(注意红色字体): [root@compute1 nova]# systemctl start ope ...