追踪记录每笔业务操作数据改变的利器——SQLCDC

对于大部分企业应用来用,有一个基本的功能必不可少,那就是Audit Trail或者Audit Log,中文翻译为追踪检查、审核检查或者审核记录。我们采用Audit

Trail记录每一笔业务操作的基本信息,比如操作的基本描述、操作时间、操作者等。对于一些安全级别比较高的应用,或者操作一些比较敏感的数据,我们甚至需要记录该笔业务操作引起的数据的改变。具体来说,这里的“数据改变”指的是每一条影响的记录在操作执行前后的变化。对于添加的记录,需要记录下新插入的记录;对于删除的记录,需要记录下原来的记录;对于更新的记录,则需要同时记录下更新前后的记录。

说到这里,很多人都会想到采用触发器的方式来实现对数据改变的捕捉。但是这种实现方案具有一个最大的局限:由于触发器是在数据操作所在事务范围内执行的,所有会带来性能的问题,严重的话还会因为触发器的执行导致事务超市。所以在这里,我们介绍一种更好的解决方案:SQLCDC。

目录
一、SQLCDC简介
二、在数据库级别开启CDC
三、为某个数据表开启CDC
四、记录添加记录的数据改变
五、记录删除数据的数据改变
六、记录更新记录的数据改变

一、SQLCDC简介

CDC的全名为Change Data Capture,顾名思义,就是用于追踪和捕捉数据改变。CDC是在SQL Server 2008中才出现的新特性,而这个特性则在很早之前就出现在了Oracle中。对于SQL Server之前版本来说,在没有CDC的情况下,如果需要记录基于某个数据表的数据改变,我们只能采用触发器,具体来说就是通过手工创建After Insert、After Update和After Delete触发器去记录变化的数据。而CDC给了我们一种更为方便、易用和省心的方式去记录某个数据表的历史操作。

二、在数据库级别开启CDC

在默认的情况下,数据库的CDC特性是被关闭的,你可以通过系统表sys.databases的is_cdc_enabled字段确定某个数据库的CDC是否开启。如果在默认的情况下,我执行如下的SQL语句查看数据库TestDb的CDC是否开启,你将会看到该字段的值为0。

你可以通过执行系统存储过程sys.sp_cdc_enable_db为当前数据库开启CDC特性。下面的T-SQL代码片断中,我们通过执行该存储过程为TestDb打开了CDC特性。

Use TestDb
Go
Exec sys.sp_cdc_enable_db
Go

三、为某个数据表开启CDC

由于CDC用于记录基于某个数据表的数据改变,所以在当前数据库CDC开启的情况下,你还需要显式地为某个数据表开启CDC特性。作为演示,我们通过如下T-SQL在TestDb下创建了一个简单的Users表,它仅仅具有三个字段:Id、Name和Birthday。

CREATE TABLE [dbo].[Users](
    [Id] [varchar](50) PRIMARY KEY,
    [Name] [nvarchar](50) NOT NULL,
    [Birthday] [date] NOT NULL)

数据表的CDC特性的开启通过执行sys.sp_cdc_enable_table存储过程实现。调用该存储过程的最简的方式就是指定数据表的Schema、名称和用于提取改变数据必须具有的权限(角色)。我通过执行下面的T-SQL将我们创建的Users表的CDC特性打开,其中@role_name参数被设置成NULL,表明我不对读取改变数据操作进行授权。sys.sp_cdc_enable_table具有很多参数,至于相应参数所影响的CDC行为,可以参考SQL
Server 2008在线文档。

Use TestDb
Go
Exec sys.sp_cdc_enable_table 'dbo', 'Users', @role_name = NULL
Go

需要注意的是,CDC实际上建立在SQL Server Agent之上的,所以在执行上述T-SQL之前需要启动SQL
Server Agent。当某个数据表的CDC特性被开启之后,系统会为创建一个用于保存数据变化的追踪表(Tracking
Table)。该表的Schema为cdc,命名方式为被追踪表的表名后加“CT”后缀。执行上面一段T-SQL之后,会有如下一个系统表被创建出来,我们发现Users表的三个字段也在该表中。此外。该表还具有5个额外字段:__$start_lsn、__$end_lsn、__$seqval、__$operation
和__$update_mask,表示日志系列号(Log Sequence Number)、操作(删除、插入、修改前和修改后)信息。

四、记录添加记录的数据改变

现在我们就可以来试验CDC针对某个数据表的数据改变的捕捉功能了,我们先来试试记录的添加操作。为此,我们执行如下一段T-SQL,插入两笔User记录。

Insert Into Users(Id, Name, Birthday)
Values ('001','Foo','1981-08-24')
 
Insert Into Users(Id, Name, Birthday)
Values ('002','Bar','1981-08-24')

然后通过如下的T-SQL查看cdc.dbo_Users_CT表的数据是否将添加操作涉及到的数据改变保存起来。从查询结果我们清晰地看到,上面添加的两笔记录已经被记录下来,而__$operation字段为2表示的是“插入”操作。

五、记录更新数据的数据改变

接下来我们来CDC对更新操作的追踪记录,为此我们通过下面的T-SQL改变了用户Foo的Birthday。

Update Users 
Set Birthday = '1982-7-10' 
Where Name = 'Foo'

再次执行对于cdc.dbo_Users_CT的全表查询,你会看到这次多了两笔记录。其中第3条记录的是修改之前的数据,而第四条则是修改之后的数据,它们的__$operation字段德值分别为3和4。

在这里值得一提的是__$update_mask字段的值,它表示的记录更新操作改变的字段。这是一个以16进制表示的数字,在进行对修改字段进行判断的时候需要将其转换成2进制。上述的更新操作对应的__$update_mask值为0x04,转化成2进制就是100,这三位分别代表3个字段。不过这里的顺序是从右到左,所以100这三位表示的字段为Birthday、Name和Id。1表示改变,0则表示保持不变。由于在上面的T-SQL中,我们只改动了Birthday,这个和100这个值是吻合的。

六、记录删除记录的数据改变

我们最后来演示当我们对记录实施删除操作的时候,CDC会为我们记录下怎样的数据。现在我们执行如下的T-SQL将Users表中所有的记录均删除。

Delete From Users

查看cdc.dbo_Users_CT的记录,多出的两笔记录正式我们删除的User记录,__$operation字段的值为1表示“删除”操作。

本篇文章仅仅是简单介绍SQLCDC的基本原理和大体上的使用方式,这篇文章《Introduction to Change Data Capture (CDC) in SQL Server 2008[转]》会给你更加详尽的介绍。如果你想深入研究SQLCDC,还是参考SQL Server 2008在线文档。

一个完整的用于追踪数据改变的解决方案

作者:蒋金楠
微信公众账号:大内老A
微博:www.weibo.com/artech
如果你想及时得到个人撰写文章以及著作的消息推送,或者想看看个人推荐的技术资料,可以扫描左边二维码(或者长按识别二维码)关注个人公众号(原来公众帐号蒋金楠的自媒体将会停用)。
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

原文链接

时间: 2024-09-22 16:16:39

追踪记录每笔业务操作数据改变的利器——SQLCDC的相关文章

link中如何记录下集合的改变,如何使用事件通知调用者呢?

问题描述 link中如何记录下集合的改变,如何使用事件通知调用者呢? link中如何记录下集合的改变,如何使用事件通知调用者呢? 解决方案 使用ObserveCollection

追踪宋林情妇业务猫腻:所在投行获多个华润项目

中国国有http://www.aliyun.com/zixun/aggregation/15530.html">大型企业集团华润集团(China Resources)董事长宋林上周被中纪委调查人员扣押.过去五年内,华润集团将多个投行交易项目给了宋林情妇所在的瑞信. 据Dealogic金融服务信息数据显示,从2009到2012年,瑞信一直是华润集团及其分公司收购和资本市场活动中最重要的顾问机构之一.这个时间段正好与杨丽娟在瑞信工作时间吻合.杨丽娟另一个名字是Helen Yang,据称她就是宋

一个完整的用于追踪数据改变的解决方案

在之前一篇介绍CDC的文章中,我说Audit Trail(或者Audit Log)是大部分企业级应用不可以或缺的功能.本篇给你一个完整的Audit Trail解决方案,不仅可以记录每一笔业务操作的信息(比如操作时间.操作者等),并且可以追踪每一笔业务引起的说有数据的改变(如果需要). 目录 一.数据表的设计 二.数据变化的表示 三.AuditLog基本信息的写入 四.通过SQLCDC追踪源表数据变化 五.删除操作的TransactionId如何被记录? 六.通过SQL Job转储AuditLog

数据库结构同步之通过DDL触发器记录数据库结构的变更

需求: 在开发多人协作的项目的时候,一般要同时使用多个数据库 常见的情况有: 一个开发者用的数据库(开发库), 一个测试者用的数据库(测试库), 一个正式开放给客户的数据库(正式库), 那么这三个数据库之间的数据结构的同步就将成为一个问题 如:当开发者A在"开发库"中添加了一个表,开发者B修改了一个表... 这些数据库结构的变更势必要同步到"测试库"和"正式库"中去 但肉手记录数据库结构变更的方式即麻烦由容易出错... 如之奈何?   思考过程:

业务架构、信息架构、技术架构三位一体

客户天天打电话要修改产品功能,简单的一个需求可能要做一个月.产品越改越笨重,为了赶工期bug越来越多.头疼! 产品从初级版到现在已经四个年头,相关的程序员来去换了三批,在补丁上打补丁是常有的事,很多功能只是开了个头,换个项目经理就被遗忘.我们总是害怕客户在这个产品上提出新的需求,只要客户还用得过去,能不改就不改.即使到了非改不可的地步,也会容忍这些僵化的代码带来的种种限制. 昨天才刚上的功能,忽然又要去掉.客户在使用产品中的这些流程,难道事先就没有人考虑到么?现在说这个功能重要,又说要做各种的接

业务架构、信息架构、技术架构三位一体,互联网营销

客户天天打电话要修改产品功能,简单的一个需求可能要做一个月.产品越改越笨重,为了赶工期bug越来越多.头疼! 产品从初级版到现在已经四个年头,相关的程序员来去换了三批,在补丁上打补丁是常有的事,很多功能只是开了个头,换个项目经理就被遗忘.我们总是害怕客户在这个产品上提出新的需求,只要客户还用得过去,能不改就不改.即使到了非改不可的地步,也会容忍这些僵化的代码带来的种种限制. 昨天才刚上的功能,忽然又要去掉.客户在使用产品中的这些流程,难道事先就没有人考虑到么?现在说这个功能重要,又说要做各种的接

mysql 批量更新与批量更新多条记录的不同值实现方法_Mysql

批量更新 mysql更新语句很简单,更新一条数据的某个字段,一般这样写: 复制代码 代码如下: UPDATE mytable SET myfield = 'value' WHERE other_field = 'other_value'; 如果更新同一字段为同一个值,mysql也很简单,修改下where即可: 复制代码 代码如下:  UPDATE mytable SET myfield = 'value' WHERE other_field in ('other_values');  这里注意

mysql 批量更新与批量更新多条记录的不同值

批量更新 mysql更新语句很简单,更新一条数据的某个字段,一般这样写:  代码如下 复制代码 UPDATE mytable SET myfield = 'value' WHERE other_field = 'other_value'; 如果更新同一字段为同一个值,mysql也很简单,修改下where即可:  代码如下 复制代码  UPDATE mytable SET myfield = 'value' WHERE other_field in ('other_values'); 这里注意 '

用友致远陷佣金门年返点百万用友行贿记录清单曝光

一位网民近日在某知名论坛网站博客中 曝光"用友致远软件行贿记录清单",清单上包括等多家政府机构和企业的详细名单.每笔业务单的返还金额.收款人等众多详细信息.博主留言称,无法接受用友这样的大公司,也必须依靠行贿来生存.荆楚网记者联系部分遭曝光的当事人,都否认收到用友致远的"佣金".截至记者发稿时,用友致远未作回应. 据了解,用友致远软件技术有限公司(UFIDA Seeyon Software Technology Co.,LTD)是由中国最大的管理软件.ERP和财务软