理解SQL Server变更数据捕获(Change Data Capture)
2015-07-12 21:46
351 查看
1.业务背景
随着公司业务的成长,数据量也随之的不断增长。随之而来的问题是在做ETL的时候,时间花费也越来越长。
为了节省时间开销,我们只想要更新最新的数据,不想要把公司历年所有的数据都进行处理。这种情况就被称为变更数据捕获(Change Data Capture,又名CDC)
2.启用SQL Server 的CDC功能
首先要确保数据库版本是企业版或者开发版,标准版是不支持CDC功能的。
SELECT is_cdc_enabled,* FROM sys.databases --查看数据库是否开启了CDC功能
EXEC sys .sp_cdc_enable_db --启用CDC功能
(如果启用时发生了错误:Could not update the metadata that indicates database ...The error returned was 15517 ,执行EXEC sp_changedbowner 'sa')
以官方的示例数据库AdventureWorks2014当中的表Employee为例,执行以下语句:
execute sp_cdc_enable_table
@source_schema=N'HumanResources'
,@source_name= N'Employee'
,@role_name= N'cdc_Admin'
,@capture_instance= N'HumanResources_Employee'
,@supports_net_changes= 1
系统会在system tables 下新建名为cdc.HumanResources_Employee_CT的追踪表。
使用SELECT 语句查看该表,可以发现该表除了保留了源表Employee一样的结构以外,同时还新增了几个额外的数据列:
试着对employee进行操作
UPDATE [HumanResources].[Employee] SET JobTitle='IT Manager' WHERE BusinessEntityID='288'
再次查看该表:
SELECT * FROM [cdc].[HumanResources_Employee_CT]
可以看到新增了两条记录,而__$operation分别对应了更新前和更新后的内容。
3.查看捕获数据
官方并不建议直接查询追踪表,可以使用官方定义好的方法cdc.fn_cdc_get_all_changes_<capture_instance> 以及 cdc.fn_cdc_get_net_changes_<capture_instance>
4.补充说明
CDC会在服务器运行一个进程,该进程从日志文件中读取更改内容,把他们写入跟踪表中。通过这样的异步处理,CDC几乎不会增加服务器的性能开销。
如果需要强制刷新而不是等待异步处理的话,运行SP: sys.sp_cdc_start_job
如果需要关闭CDC,运行SP: sp_cdc_disable_table
版权声明:本文为博主原创文章,未经博主允许不得转载。
随着公司业务的成长,数据量也随之的不断增长。随之而来的问题是在做ETL的时候,时间花费也越来越长。
为了节省时间开销,我们只想要更新最新的数据,不想要把公司历年所有的数据都进行处理。这种情况就被称为变更数据捕获(Change Data Capture,又名CDC)
2.启用SQL Server 的CDC功能
首先要确保数据库版本是企业版或者开发版,标准版是不支持CDC功能的。
SELECT is_cdc_enabled,* FROM sys.databases --查看数据库是否开启了CDC功能
EXEC sys .sp_cdc_enable_db --启用CDC功能
(如果启用时发生了错误:Could not update the metadata that indicates database ...The error returned was 15517 ,执行EXEC sp_changedbowner 'sa')
以官方的示例数据库AdventureWorks2014当中的表Employee为例,执行以下语句:
execute sp_cdc_enable_table
@source_schema=N'HumanResources'
,@source_name= N'Employee'
,@role_name= N'cdc_Admin'
,@capture_instance= N'HumanResources_Employee'
,@supports_net_changes= 1
系统会在system tables 下新建名为cdc.HumanResources_Employee_CT的追踪表。
使用SELECT 语句查看该表,可以发现该表除了保留了源表Employee一样的结构以外,同时还新增了几个额外的数据列:
Column name | Description |
__$start_lsn | 表示操作的顺序,同一个transaction的lsn号相同 |
__$end_lsn | 始终为null |
__$seqval | transaction内操作的顺序 |
__$operation | 引起更改的源操作 |
1 = 删除 | |
2 = 插入 | |
3 = 更新 (前映像) | |
4 = 更新 (后映像) | |
5 = 合并 | |
__$update_mask | 表示哪些特定列发生了更改。需要通过sys.fn_cdc_has_columns_changed等函数来理解该列的意义 |
UPDATE [HumanResources].[Employee] SET JobTitle='IT Manager' WHERE BusinessEntityID='288'
再次查看该表:
SELECT * FROM [cdc].[HumanResources_Employee_CT]
可以看到新增了两条记录,而__$operation分别对应了更新前和更新后的内容。
3.查看捕获数据
官方并不建议直接查询追踪表,可以使用官方定义好的方法cdc.fn_cdc_get_all_changes_<capture_instance> 以及 cdc.fn_cdc_get_net_changes_<capture_instance>
DECLARE @from_lsn binary(10), @to_lsn binary(10); SET @from_lsn = sys.fn_cdc_get_min_lsn('HumanResources_Employee'); SET @to_lsn = sys.fn_cdc_get_max_lsn(); SELECT * FROM cdc.fn_cdc_get_all_changes_HumanResources_Employee(@from_lsn, @to_lsn, N'all')--返回LSN所有更改行 SELECT * FROM cdc.fn_cdc_get_net_changes_HumanResources_Employee(@from_lsn, @to_lsn, N'all');--返回LSN最终结果
4.补充说明
CDC会在服务器运行一个进程,该进程从日志文件中读取更改内容,把他们写入跟踪表中。通过这样的异步处理,CDC几乎不会增加服务器的性能开销。
如果需要强制刷新而不是等待异步处理的话,运行SP: sys.sp_cdc_start_job
如果需要关闭CDC,运行SP: sp_cdc_disable_table
版权声明:本文为博主原创文章,未经博主允许不得转载。
相关文章推荐
- oracle锁表解表
- 【转】关于redis.conf的参数配置
- Atitit.升级软件的稳定性---基于数据库实现持久化 循环队列 循环队列
- mysql意向锁的概念和用途
- mysql拒绝远程访问
- Sql sever 分组排序
- MySQL系列之F-3------MySQL恢复
- 使用NFS安装oracle软件
- MySQL系列之F-2------mysqldump -help
- MySQL系列之F------MySQL备份
- 一键安装ORACLE并建库脚本
- Oracle 数据迁移(从Oracle11G迁移到更高的版本号Oracle10G低版本号)
- 用PHP向数据库中实现简单的增删改查(纯代码)
- MySQL系列之E-2------MySQL主从复制实战
- 数据库 -- MYSQL免安装操作方法
- Memcahce(MC)系列(三)Memcached它PHP转让
- 基于mariadb的日志服务器及用loganalyzer实现日志的管理分析 推荐
- MySQL系列之E-1------MySQL主从复制原理
- Hive格式化输出数据库和表详细信息
- MySQL系列之D-2------MySQL多实例添加一个实例