一.本文所涉及的内容(Contents)

  1. 本文所涉及的内容(Contents)
  2. 背景(Contexts)
  3. 实现过程(Realization)
  4. 补充说明(Addon)
  5. 参考文献(References)

二.背景(Contexts)

  在SQL Server 2008版本之前,对表数据库的变更监控,我们通常使用DML触发器进行监控,把DML操作中的INSERT/UPDATE/DELETE数据记录下来,但是触发器的维护比较困难;

  当SQL Server 2008新功能:变更数据捕获(Change Data Capture,即CDC)出来之后,我发现这正是我想要的,因为我之前使用DML触发器实现的时候也是把UPDATE操作按照两条记录进行记录的,共同的缺点都是在用户修改了表结构后,CDC不会自动同步到记录中,不过CDC也有DDL的监控可以补充这个缺陷;CDC的优点就是以异步进程读取事务日志进行捕获数据变更的。

三.实现过程(Realization)

(一) 创建一个测试数据库;

/******* Step1:创建示例数据库*******/
USE master
GO
IF EXISTS(SELECT name FROM sys.databases WHERE name = 'CDC_DB')
DROP DATABASE CDC_DB
GO
CREATE DATABASE CDC_DB
GO

(二) 在开启数据库的CDC之前先查询一下状态,is_cdc_enabled值为0表示没有开启,1表示开启,当为数据库[CDC_DB]启用了CDC之后,在CDC_DB系统表中会出现下图Figure2所示的6个表;

/******* Step2:开启数据库CDC *******/
--查看数据库是否启用CDC
SELECT name,is_cdc_enabled FROM sys.databases WHERE name = 'CDC_DB' --启用数据库CDC
USE CDC_DB
GO
EXECUTE sys.sp_cdc_enable_db;
GO --检查启用是否成功
SELECT is_cdc_enabled,CASE WHEN is_cdc_enabled=0 THEN 'CDC功能禁用' ELSE 'CDC功能启用' END 描述
FROM sys.databases
WHERE NAME = 'CDC_DB'

(Figure1:数据库CDC状态)

(Figure2:启用数据库CDC创建的系统表)

(Figure3:数据库CDC状态)

(Figure4:添加新用户和架构)

开启数据库的CDC之后,分别在用户和架构上创建新的用户cdc,新的架构cdc;

(三) 创建一个测试表,对表行变更启用捕获,为表[Department]启用CDC,首先会在系统表中创建[cdc].[dbo_Department_CT],会在Agent中创建两个作业,cdc.CDC_DB_capture和cdc.CDC_DB_cleanup,启用表变更捕获需要开启SQL Server Agent服务,不然会报错。每对一个表启用捕获就会生成一个向对应的记录表。

/******* Step3:对表启用变更捕获*******/
--创建测试表
USE CDC_DB
GO
CREATE TABLE [dbo].[Department](
[DepartmentID] [smallint] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](200) NULL,
[GroupName] [nvarchar](50) NOT NULL,
[ModifiedDate] [datetime] NOT NULL,
[AddName] [nvarchar](120) NULL,
CONSTRAINT [PK_Department_DepartmentID] PRIMARY KEY CLUSTERED
(
[DepartmentID] ASC
) ON [PRIMARY]
) ON [PRIMARY]
GO --对表启用捕获
EXEC sys.sp_cdc_enable_table
@source_schema= 'dbo',
@source_name = 'Department',
@role_name = N'cdc_Admin',
@capture_instance = DEFAULT,
@supports_net_changes = 1,
@index_name = NULL,
@captured_column_list = NULL,
@filegroup_name = DEFAULT --检查是否成功
SELECT name, is_tracked_by_cdc ,
CASE WHEN is_tracked_by_cdc = 0 THEN 'CDC功能禁用' ELSE 'CDC功能启用' END 描述
FROM sys.tables
WHERE OBJECT_ID= OBJECT_ID('dbo.Department') --返回某个表的变更捕获配置信息
EXEC sys.sp_cdc_help_change_data_capture 'dbo', 'Department'

(Figure5:提示信息)

(Figure6:新增加的系统表)

(Figure7:生成的捕获和清理作业)

(Figure8:表的CDC状态)

(Figure9:多了个数据库角色)

(Figure10:sys.sp_cdc_enable_table配置选项)

上图深色部分的字段值是在执行sys.sp_cdc_enable_table的时候设置的。

(四) 测试插入数据、更新数据、删除数据,执行完这些DML,我们来观察下cdc.dbo_Department_CT帮我们记录些什么?

/******* Step4:测试DML变更捕获*******/
--测试插入数据
INSERT INTO dbo.Department(
Name ,
GroupName ,
ModifiedDate
)VALUES('Marketing','Sales and Marketing',GETDATE()) --测试更新数据
UPDATE dbo.Department SET Name = 'Marketing Group',ModifiedDate = GETDATE()
WHERE Name = 'Marketing' --测试删除数据
DELETE FROM dbo.Department WHERE Name='Marketing Group' --查询捕获数据
SELECT * FROM cdc.dbo_Department_CT

(Figure11:变更记录表)

对于insert/delete操作,会有对应的一行记录,而对于update,会有两行记录。__$operation列:1 = 删除、2= 插入、3= 更新(旧值)、4= 更新(新值);

(五) 启用CDC之后,你怎么从中获取到数据呢?通过数据我们可以对数据进行恢复;

/******* Step6:使用LSN 查看CDC记录*******/
--http://msdn.microsoft.com/zh-cn/library/bb500137%28v=sql.100%29.aspx
SELECT sys.fn_cdc_map_time_to_lsn
('smallest greater than or equal', '2013-07-24 09:00:30') AS BeginLSN SELECT sys.fn_cdc_map_time_to_lsn
('largest less than or equal', '2013-07-24 23:59:59') AS EndLSN /******* 查看某时间段所有CDC记录*******/
DECLARE @FromLSN binary(10) =
sys.fn_cdc_map_time_to_lsn
('smallest greater than or equal' , '2013-06-23 09:00:30') DECLARE @ToLSN binary(10) =
sys.fn_cdc_map_time_to_lsn
('largest less than or equal' , '2013-07-26 23:59:59') SELECT CASE [__$operation]
WHEN 1 THEN 'DELETE'
WHEN 2 THEN 'INSERT'
WHEN 3 THEN 'Before UPDATE'
WHEN 4 THEN 'After UPDATE'
END Operation,[__$operation],[__$update_mask],DepartmentId,Name,GroupName,ModifiedDate,AddName
FROM [cdc].[fn_cdc_get_all_changes_dbo_Department]
(@FromLSN, @ToLSN, N'all update old')
/*
all 其中的update,只包含新值
all update old 包含新值和旧值
*/

(Figure15:通过时间获取LSN更新)

(六) CDC的维护

/******* Step5:维护CDC *******/
--返回所有表的变更捕获配置信息
EXECUTE sys.sp_cdc_help_change_data_capture; --返回某个表的变更捕获配置信息
EXEC sys.sp_cdc_help_change_data_capture 'dbo', 'Department' --查看对某个表的哪些列做了捕获监控,使用上面返回的capture_instance列值
EXEC sys.sp_cdc_get_captured_columns
@capture_instance = 'dbo_Department'

(Figure12:监控表字段信息)

由于sys.sp_cdc_enable_table 的参数:@captured_column_list = NULL,所以dbo.Department表的所有字段都进行监控了,如果你只关心某些字段,强烈建议在创建捕获的时候设置这个属性;

--所有数据库CDC Job信息
SELECT B.name,A.* FROM msdb.dbo.cdc_jobs AS A
LEFT JOIN sys.databases AS B
ON A.database_id = B.database_id --当前数据库CDC Job信息
EXEC sp_cdc_help_jobs

(Figure13:数据库作业信息)

四.补充说明(Addon)

  SQL Server记录数据变更有四种方法:触发器、Output子句、变更数据捕获(Change Data Capture 即CDC)功能、同步更改跟踪。其中后两个为SQL Server 2008所新增。

CDC功能主要捕获SQLServer指定表的增删改操作;

CDC除了捕获数据变更之外,还能捕获DDL操作的变化;

无法对系统数据库和分发数据库启用该功能。且执行者需要用sysadmin角色权限;

cdc.<capture_instance>_CT   可以看到,这样命名的表,是用于记录源表更改的表。对于insert/delete操作,会有对应的一行记录,而对于update,会有两行记录;

对于__$start_lsn列:由于更改是来源与数据库的事务日志,所以这里会保存其事务日志的开始序列号(LSN);

对于__$end_lsn列:

对于__$seqval列:

对于__$operation列:1 = 删除、2= 插入、3= 更新(旧值)、4= 更新(新值);

对于__$update_mask列:

恢复模式为简单模式一样可以进行CDC;

虽然能捕获到数据变更,但是没有办法找到是谁更新的?

能使用这个做回滚嘛?备份的另外一种路径?对表更新不频繁的情况下?

如果是添加或者删除了某些字段DDL,那么创建的CDC表并没有做更改,那新字段的数据怎么捕获呢?修改字段长度等这些操作同样会一起修改CDC对应的表字段;

sys.sp_cdc_enable_table 的@role_name参数,是指角色-数据库角色,这个有什么用呢?应用程序角色又有什么用呢?

cdc.Person_Contact_CT这名字中CT代表什么意思呢?Capture Table?(用户.架构_表_CT)

SQL Server 自启动了两个job,一个捕获,一个清除,注意清除是默认凌晨2点,清除72小时以上的数据。如果同一数据库的表中CDC已经启用,不会重建job。

all

返回指定 LSN 范围内的所有更改。 对于由更新操作导致的更改,此选项只返回在应用更新之后包含新值的行。

all update old

返回指定 LSN 范围内的所有更改。 对于由更新操作导致的更改,此选项将返回在更新之前包含列值的行和更新之后包含列值的行。

文章出处:http://www.cnblogs.com/gaizai/p/3479731.html

SQL Server ---(CDC)监控表数据(转译)的更多相关文章

  1. sql server 通用修改表数据存储过程

    ALTER PROC [dbo].[UpdateTableData] ), ), ), ), ) AS BEGIN ) SET @sql ='UPDATE '+@TableName; --获取SqlS ...

  2. SQL Server 中树形表数据的处理总结

    -- 使用函数的方法: --建立 演示环境 if object_id('tb_bookInfo') is not null drop table tb_bookInfo go ),type int) ...

  3. sql server 清空数据库表数据

    --禁用外键约束 exec   sp_msforeachtable   'alter   table   ?   nocheck   constraint   all ' --清空数据 truncat ...

  4. SQL Server 更改跟踪(Chang Tracking)监控表数据

    一.本文所涉及的内容(Contents) 本文所涉及的内容(Contents) 背景(Contexts) 主要区别与对比(Compare) 实现监控表数据步骤(Process) 参考文献(Refere ...

  5. 【转载,备忘】SQL Server 更改跟踪(Chang Tracking)监控表数据

    一.本文所涉及的内容(Contents) 本文所涉及的内容(Contents) 背景(Contexts) 主要区别与对比(Compare) 实现监控表数据步骤(Process) 参考文献(Refere ...

  6. 在SQL SERVER中获取表中的第二条数据

    在SQL SERVER中获取表中的第二条数据, 思路:先根据时间逆排序取出前2条数据作为一个临时表,再按顺时排序在临时表中取出第一条数据 sql语句如下: select top 1 * from(se ...

  7. 快速查看SQL Server 中各表的数据量以及占用空间大小

    快速查看SQL Server 中各表的数据量以及占用空间大小. CREATE TABLE #T (NAME nvarchar(100),ROWS char(20),reserved varchar(1 ...

  8. sql Server中临时表与数据表的区别

    sql server 中临时表与数据表的区别 1.如何判断临时表和数据表已生成 --如何判断临时表是否已创建--- if exists(select * from tempdb..sysobjects ...

  9. 转:Sql Server中清空所有数据表中的记录

    如果要删除数据表中所有数据只要遍历一下数据库再删除就可以了,清除所有数据我们可以使用搜索出所有表名,构造为一条SQL语句进行清除了,这里我一一给各位同学介绍.   使用sql删除数据库中所有表是不难的 ...

随机推荐

  1. sql中 in , not in , exists , not exists效率分析

    in和exists执行时,in是先执行子查询中的查询,然后再执行主查询.而exists查询它是先执行主查询,即外层表的查询,然后再执行子查询. exists 和 in 在执行时效率单从执行时间来说差不 ...

  2. Android对话框自定义标题

    Android自带的对话框标题不好看,如果我们需要给弹出的对话框设置一个自己定义的标题,可以使用AlertDialog.Builder的setCustomTitle()方法. 定义一个对话框标题的ti ...

  3. Firemonkey 调整 MainMenu 字型大小 (D10)

    修改 Windows 下的 Style,找到下面二个 Style ,修改其中的 text 内的 font 大小: 将 FMX.Menus.pas 复制到自己的工程目录内,再修改如下内容: constr ...

  4. [转]以Facebook为案例剖析科技公司应有的工具文化

    原文:http://36kr.com/p/146507.html 这是一篇几年前的文章,但对于没有涉及到工具文化这个概念的人来说,还是很新的. 前言 前段时间和大众点评的 CEO 张涛聊天的时候碰到内 ...

  5. SSO单点登录实现原理与总结

    一.什么是单点登录SSO(Single Sign-On) SSO是一种统一认证和授权机制,指访问同一服务器不同应用中的受保护资源的同一用户,只需要登录一次,即通过一个应用中的安全验证后,再访问其他应用 ...

  6. SQLServer2008部署镜像

    SQL Server 2008 R2数据库镜像部署 概述 “数据库镜像”是一种针对数据库高可用性的基于软件的解决方案.其维护着一个数据库的两个相同的副本,这两个副本分别放置在不同的SQL Server ...

  7. phonegap安卓手机开发入门

    先安装安卓开发安环境 http://www.cnblogs.com/zhangsanshi/p/3582368.html 安装phonegap 在安装ant http://www.cnblogs.co ...

  8. Bootstrap源码分析之nav、collapse

    导航分析(nav): 源码文件:_navs.scss:导航模块Mixins/_nav-divider.scss:分隔线Mixins/_nav-vertical-align.scss:垂直对齐 1.只是 ...

  9. jQuery 特效:盒子破碎和移动动画效果

    今天,我们将创建一个使用 jQuery 制作的非常甜蜜的动画效果.我们的想法是在网站的顶部有小盒子,当一个菜单项被点击时,箱子动画形成的主要内容区域分散在各处.我们会用一些不同的动画效果,我们将为菜单 ...

  10. 轻松掌握:JavaScript装饰者模式

    装饰者模式 在传统的面向对象语言中,给对象添加功能常常使用继承的方式,但继承的方式会带来问题:当父类改变时,他的所有子类都将随之改变. 当JavaScript脚本运行时,在一个对象中(或他的原型上)增 ...