在日常应用中经常会有这样的需求,需要audit那些数据更改,,或者需要跟踪更改的数据实现对数据的同步。(最常见的应用如数据仓库数据同步,因为数据量巨大,需要将数据的更改同步到数据仓库,这种同步不要求实时)。
通常的做法是自定义应用程序使用比如触发器、timestamp 列和新表组合来存储跟踪信息,同事还需要自定义清除程序清除过时的数据。在sql server 2008以后提供了一个功能更改跟踪(change tracking).这一种轻量型解决方案(相对于自己自定义的程序,性能要高)为应用程序提供了一种有效的更改跟踪机制。
注意:用程序需要有关所有所做更改的信息以及所更改数据的中间值,则可能适合使用变更数据捕获,而不适合使用更改跟踪。
工作原理:为表配置了更改跟踪后,任何影响该表中的行的 dml 语句都将导致针对每个有所修改的行的更改跟踪信息被记录下来。更改信息会记录到sql server内部表中,可以使用查询到内部表,使用changetable函数获得数据更改信息。
下面是启动change tracking并且获得更改数据的脚本:
--创建测试数据库和表
go
20)null,
(
[maxid] asc
--在数据库和表启动更改跟踪:
2
-- auto_cleanup = on在经过指定的保持期后会自动删除更改跟踪信息。
enable change_tracking
如果表没有主键启动更改跟踪会出现下面的错误:
msg 4997, level16, state 1, line 1
cannot enablechange tracking on table 'a'. change tracking requires a primary key on thetable. create a primary key on the table before enabling change tracking.
原因:主键列值是来自所跟踪的并记录更改信息的表中的唯一信息。这些值用于标识发生更改的行。要获取这些行的最新数据,应用程序可以使用主键列值联接源表和所跟踪的表。
(也可以在ssms中启用更改跟踪)
-- 查询数据库和表更改跟踪信息
--返回与上次提交的事务相关联的版本
--指定的表中获取更改跟踪信息的最低版本
0
--插入测试数据并且查询跟踪信息最新版本号
1
2
go
go
1
go
0
2
--将更改跟踪信息与原表信息关联获得最新数据(这些数据就是我们需要同步的数据)
2
go
0
go
changetable返回值:
注意:
如果执行了truncate table或者cleanup进程清理了change tracking记录,那么可以通过change_tracking_min_valid_version函数了解可获取的最小更新版本号。如果这个最小版本号比复制目的端记录的最近一次复制成功的最大版本号都高,则意味着源数据库已经丢失了一部份尚未复制的记录,也就代表目的系统需要重新初始化。对于update语句,如果在启用表的change tracking功能是设置了track_column_updated选项为on,change tracking会记录下update语句影响到字段信息,这个信息可以通过使用change_tracking_is_column_in_mask函数解析,比如说要知道testct表的name字段是否在版本2的update操作中被影响到,可以使用change_tracking_is_column_in_mask(columnproperty(object_id('testct'), 'name', 'columnid'), sys_change_columns)函数。
更多信息参考msdn:更改跟踪概述
