SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑
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的数据库上执行脚本如下:
- if exists(select 1 from sys.databases where name='db_name' and is_cdc_enabled=0)
- begin
- exec sys.sp_cdc_enable_db
- end
2、查询数据库的cdc开启状态
- select is_cdc_enabled from sys.databases where name='db_name'
查询结果为“1”,表示开启成功。
2.3、开启表CDC
*注意:表中必须有主键或者唯一索引
1、添加次要数据文件组及文件
数据库右键“属性” >> “文件组”>> ”添加”
“文件” >> “添加”
2、执行以下脚本,开启表cdc

- --CDC是数据库文件组的名称
- IF EXISTS(SELECT 1 FROM sys.tables WHERE name='table_name' AND is_tracked_by_cdc = 0)
- BEGIN
- EXEC sys.sp_cdc_enable_table
- @source_schema = 'dbo', -- source_schema
- @source_name = 'table_name', -- table_name
- @capture_instance = NULL, -- capture_instance
- @supports_net_changes = 1, -- supports_net_changes
- @role_name = NULL, -- role_name
- @index_name = NULL, -- index_name
- @captured_column_list = NULL, -- captured_column_list
- @filegroup_name = 'CDC' -- filegroup_name
- END

3、查看表cdc开启状态
- 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选项
- --在数据库级别启用CDC功能
- EXEC sys.sp_cdc_enable_db
这个命令执行完之后,会在系统表里面添加6个表格
3.在需要做数据捕获的表上面启用CDC选项
- EXEC sys.sp_cdc_enable_table
- @source_schema='dbo',
- @source_name='Orders',
- @capture_instance='Orders',
- @supports_net_changes=0,
- @role_name=null
【备注】关于这个存储过程的具体用法和有关参数的含义,请参考
http://msdn.microsoft.com/en-us/library/bb522475.aspx
执行之后,会有如下的输出消息
这个提示的意思是说,要启动SQL Server Agent。因为CDC功能是要通过一个两个作业来自动化完成的
与此同时,执行上面的命令还将在系统表中添加一个表格
还会添加一个函数
4.插入或者更新数据测试CDC功能
- --插入或者更新数据测试CDC功能
- INSERT Orders(CustomerID) VALUES('Microsoft');
- INSERT Orders(CustomerID) VALUES('Google');
- UPDATE Orders SET CustomerID='Yahoo' WHERE OrderID=1
- DELETE FROM Orders WHERE OrderID=2
这个范例插入两行数据,紧接着又对第一行更新,然后还删除了第二行,所以最终只有一行数据
那么,我们来看看CDC做了什么事情呢?
- SELECT * FROM cdc.Orders_CT
我们可以来解释一下上面结果的含义
__$operation=2的情况,表示新增
__$operation=3或者4,表示更新,3表示旧值,4表示新值
__$operation=1的情况,表示删除
很好理解,不是吗?
但是,我们一般都是需要按照时间范围进行检索,对吧,所以,需要使用下面的语法进行查询
- --按照时间范围查询CDC结果
- DECLARE @from_lsn BINARY(10),@end_lsn BINARY(10)
- DECLARE @start_time DATETIME = '2011-8-10 00:00:00'
- DECLARE @end_time DATETIME ='2011-8-11 00:00:00'
- SELECT @from_lsn=sys.fn_cdc_map_time_to_lsn('smallest greater than or equal',@start_time)
- SELECT @end_lsn=sys.fn_cdc_map_time_to_lsn(' largest less than or equal',@end_time)
- 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
查询的结果如下
如果需要包含更新操作的旧值,则可以以下的语法
- DECLARE @from_lsn BINARY(10),@end_lsn BINARY(10)
- DECLARE @start_time DATETIME = '2011-8-10 00:00:00'
- DECLARE @end_time DATETIME ='2011-8-11 00:00:00'
- SELECT @from_lsn=sys.fn_cdc_map_time_to_lsn('smallest greater than or equal',@start_time)
- SELECT @end_lsn=sys.fn_cdc_map_time_to_lsn(' largest less than or equal',@end_time)
- SELECT * FROM cdc.fn_cdc_get_all_changes_Orders(@from_lsn,@end_lsn,'all update old')
通常,为了方便起见,我们会将这个查询定义为一个存储过程,如下
- --定义存储过程来进行查询
- CREATE PROC GetOrdersCDCResult(@start_time DATETIME,@end_time DATETIME)
- AS
- BEGIN
- DECLARE @from_lsn BINARY(10),@end_lsn BINARY(10)
- SELECT @from_lsn=sys.fn_cdc_map_time_to_lsn('smallest greater than or equal',@start_time)
- SELECT @end_lsn=sys.fn_cdc_map_time_to_lsn(' largest less than or equal',@end_time)
- SELECT * FROM cdc.fn_cdc_get_all_changes_Orders(@from_lsn,@end_lsn,'all')
- END
然后,每次需要用的时候,就直接调用即可
- --执行存储过程
- EXEC GetOrdersCDCResult '2011-8-10','2011-8-11'
5.结合SSIS实现事实表的增量更新
下面展示了一个SSIS 包的设计,这里面读取CDC的数据,先进行一些查找,然后按照__$operation的值拆分成为三个操作,分别进行插入,更新和删除,这样就可以实现对事实表的增量更新
本文所有的代码如下
- USE SampleDatabase
- GO
- --在数据库级别启用CDC功能
- EXEC sys.sp_cdc_enable_db
- --在需要做数据捕获的表格上面启用CDC功能
- EXEC sys.sp_cdc_enable_table
@source_schema='dbo',
@source_name='Orders',
@capture_instance='Orders',
@supports_net_changes=0,
@role_name=null- --插入或者更新数据测试CDC功能
- INSERT Orders(CustomerID) VALUES('Microsoft');
- INSERT Orders(CustomerID) VALUES('Google');
- UPDATE Orders SET CustomerID='Yahoo' WHERE OrderID=1
- DELETE FROM Orders WHERE OrderID=2
- --查询CDC的结果
- SELECT * FROM cdc.Orders_CT
- --按照时间范围查询CDC结果
- DECLARE @from_lsn BINARY(10),@end_lsn BINARY(10)
- DECLARE @start_time DATETIME = '2011-8-10 00:00:00'
- DECLARE @end_time DATETIME ='2011-8-11 00:00:00'
- SELECT @from_lsn=sys.fn_cdc_map_time_to_lsn('smallest greater than or equal',@start_time)
- SELECT @end_lsn=sys.fn_cdc_map_time_to_lsn(' largest less than or equal',@end_time)
- SELECT * FROM cdc.fn_cdc_get_all_changes_Orders(@from_lsn,@end_lsn,'all')
- --定义存储过程来进行查询
- CREATE PROC GetOrdersCDCResult(@start_time DATETIME,@end_time DATETIME)
- AS
- BEGIN
- DECLARE @from_lsn BINARY(10),@end_lsn BINARY(10)
- SELECT @from_lsn=sys.fn_cdc_map_time_to_lsn('smallest greater than or equal',@start_time)
- SELECT @end_lsn=sys.fn_cdc_map_time_to_lsn(' largest less than or equal',@end_time)
- SELECT * FROM cdc.fn_cdc_get_all_changes_Orders(@from_lsn,@end_lsn,'all')
- END
- --执行存储过程
- EXEC GetOrdersCDCResult '2011-8-10','2011-8-11'
SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑的更多相关文章
- SQL Server 2008中新增的 1.变更数据捕获(CDC) 和 2.更改跟踪
概述 1.变更数据捕获(CDC) 每一次的数据操作都会记录下来 2.更改跟踪 只会记录最新一条记录 以上两种的区别: http://blog.csdn.n ...
- SQL Server 2008中新增的变更数据捕获(CDC)和更改跟踪
来源:http://www.cnblogs.com/downmoon/archive/2012/04/10/2439462.html 本文主要介绍SQL Server中记录数据变更的四个方法:触发器 ...
- SQL Server 2008中的数据压缩
SQL Server 2008中引入了数据压缩的功能,允许在表.索引和分区中执行数据压缩.这样不仅可以大大节省磁盘的占用空间,还允许将更多数据页装入内存中,从而降低磁 盘IO,提升查询的性能.当然,凡 ...
- SQL Server 2008中数据压缩
SQL Server 2008中引入了数据压缩的功能,允许在表.索引和分区中执行数据压缩.这样不仅可以大大节省磁盘的占用空间,还允许将更多数据页装入内存中,从而降低磁盘IO,提升查询的性能.当然,凡事 ...
- SQL点滴15—在SQL Server 2008中调用C#程序
原文:SQL点滴15-在SQL Server 2008中调用C#程序 T-SQL的在执行普通的查询的时候是很高效的,但是在执行循环,判断这样的语句的时候效率就不那么的高了.这时可以借助CLR了,我们可 ...
- 在SQL Server 2008中调用.net,dll
原文:在SQL Server 2008中调用.net,dll T-SQL的在执行普通的查询的时候是很高效的,但是在执行循环,判断这样的语句的时候效率就不那么的高了.这时可以借助CLR了,我们可以在SQ ...
- SQL SERVER 2008中使用VARBINARY(MAX)进行图像存取的实现方法
在数据库应用项目开发中,经常会使用一些二进制的图像数据,存储和读取显示图像数据主要采用的是路径链接法和内存流法.路径链接法是将图像文件保存在固定的路径下,数据库中只存储图像文件的路径和名称 ...
- SQL Server 2008中增强的"汇总"技巧
本文转载:http://www.cnblogs.com/downmoon/archive/2012/04/06/2433988.html SQL Server 2008中的Pivot和UnPivot: ...
- 利用Ring Buffer在SQL Server 2008中进行连接故障排除
原文:利用Ring Buffer在SQL Server 2008中进行连接故障排除 出自:http://blogs.msdn.com/b/apgcdsd/archive/2011/11/21/ring ...
随机推荐
- ANTLR v4 专业术语集
记录<The Definitive ANTLR 4 Reference>中出现的专业术语: grammar 文法,一种形式化(formal)的语言描述. syntax 语法 phrase ...
- Android 开发笔记
11.android使用全局变量 定义Data类继承Application 在manifest.xml中声明 http://blog.csdn.net/feiyangxiaomi/article/de ...
- 关于在最新的 Visual Studio 2017 版本中使用 Web Deploy 遇到的 SSL 连接错误
错误信息: 无法完成向远程代理 URL 发送请求.请求被中止: 未能创建 SSL/TLS 安全通道. 原因分析: 最新版本的 Visual Studio 中,已经抛弃了 https 协议中旧版 SSL ...
- 基于Python37配置图片文字识别
以管理员权限打开cmd控制台. 1.如何安装PIL 输入下面命令:pip install Pillow 参考:https://www.cnblogs.com/mrgavin/p/8177841.htm ...
- Fluent动网格【11】:弹簧光顺
动网格除了前面讲了很多的关于运动指定之外,另一个重要主题则为网格的更新. 在部件运动之后,不可避免的会造成网格形状的变化,如若不对网格加以控制,在持续运动的过程中,则可能造成网格极度变形.歪曲率过大, ...
- ss搭建
aliyun ecs ,hongkong , t5 , 1M, 1.卸载阿里云盾监控 wget http://update.aegis.aliyun.com/download/uninstall.sh ...
- VS2013-2017 舒服的字体设置和背景色
使用字体:Fixedsys Excelsior 3.01 1.如果没有安装字体的话,首先下载字体:http://www.fixedsysexcelsior.com/ 2.安装字体:控制面板 -> ...
- Cookie详解整理
1.Cookie的诞生 由于HTTP协议是无状态的,而服务器端的业务必须是要有状态的.Cookie诞生的最初目的是为了存储web中的状态信息,以方便服务器端使用.比如判断用户是否是第一次访问网站.目前 ...
- greenplum 安装笔记
折腾两天了,终于把greenplum装成功了.记录下遇到的问题. 环境变量一点要配置准确. greenplum安装,按照这里一步步走: http://www.cnblogs.com/liuyungao ...
- [原][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 ...