一.本文所涉及的内容(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. 背水一战 Windows 10 (2) - UI: 概述, 启动屏幕, 屏幕方向

    [源码下载] 背水一战 Windows 10 (2) - UI: 概述, 启动屏幕, 屏幕方向 作者:webabcd 介绍背水一战 Windows 10 之 UI UI 设计概述 启动屏幕(闪屏) 屏 ...

  2. iOS6.0下获取通讯录用户列表

    自iOS6.0后获取通讯录列表需要询问用户,经过用户同意后才可以获取通讯录用户列表.而且ABAddressBookRef的初始化工作也由ABAddressBookCreate函数转变为ABAddres ...

  3. ==与equals()

    java中的比较有很多种 1.== 2.equals() 3.< 或 >或 != 4.instanceof 5.compareTo 1.什么时候用"==" 什么时候用& ...

  4. Java就业指导

    想要成为合格的Java程序员或工程师到底需要具备哪些专业技能,面试者在面试之前到底需要准备哪些东西呢?本文陈列的这些内容既可以作为个人简历中的内容,也可以作为面试的时候跟面试官聊的东西,你可以把这些内 ...

  5. 一个java实习生两周八次的面试经历

    以前从来没有因为求职出去面试过,一直觉得面试很可怕,没想到最近两周我也成为了面霸,两周面试八次,我的找工作之路就这样开始了!大概两个星期之前,我看着自己在招聘网站上写好的简历连投出去的勇气都没有,战战 ...

  6. python补充最常见的内置函数

    最常见的内置函数是: print("Hello World!") 数学运算 abs(-5)                         # 取绝对值,也就是5 round(2. ...

  7. CI框架源码阅读笔记4 引导文件CodeIgniter.php

    到了这里,终于进入CI框架的核心了.既然是“引导”文件,那么就是对用户的请求.参数等做相应的导向,让用户请求和数据流按照正确的线路各就各位.例如,用户的请求url: http://you.host.c ...

  8. mysql登录时闪退的问题

    之前mysql用着好着,可是今天在启动mysql后输入密码出现了闪退,在任务管理器中发现mysql服务没有启动,当手动启动时提示拒绝访问.在网上查找原因发现问题所在. 问题原因:mysql服务没有安装 ...

  9. Code First :使用Entity. Framework编程(4) ----转发 收藏

    第4章 对关系使用默认规则与配置 在第3章,你已经掌握了默认规则与配置对属性以及其在数据库映射的字段的影响.在本章,我们把焦点放在类之间的关系上面.这包括类在内存如何关联,还有数据库中的外键维持等.你 ...

  10. sizzle源码分析 (3)sizzle 不能快速匹配时 选择器流程

    如果快速匹配不成功,则会进入sizzle自己的解析顺序,主要流程如下: 总结流程如下: (1)函数sizzle是sizzle的入口,如果能querySelectAll快速匹配,则返回结果 (2)函数S ...