数据源
1.SQL server 2008版本以上的企业版、开发版和评估版中可用;
2.需要开启代理服务(作业)。
打开sql server配置管理器->启动SqlServer Agent
Sql Server Configuration Manager操作如下:
3.CDC需要业务库之外的额外的磁盘空间。
相当于业务库需要开通的CDC的库和表的所占磁盘空间
4.CDC的表需要主键或者唯一索引(serversql 2017需要)。
准备工作
1,开启数据库级别的cdc功能
USE [库名];
GO
EXEC sys.sp_cdc_enable_db;
2,验证数据库级别的cdc是否开启
use [库名];
SELECT name, is_cdc_enabled
FROM sys.databases WHERE database_id = DB_ID();
执行结果:is_cdc_enabled等于1是开启,等于0是没有开启
如图ZEE这个数据库已开启了CDC
3,开启表级别的cdc(需要开通库级别的cdc)
--开通某张表的cdc
执行下面的sql可以开启库名为ZEE, 架构名称为dbo,表名为Test的表的CDC服务
其中: source_schema= 架构名称
source_name = 表名
capture_instance = 架构名称_表名
USE ZEE
GO
EXEC sys.sp_cdc_enable_table
@source_schema = N'dbo',
@source_name = N'Test',
@role_name = NULL,
@capture_instance = N'dbo_Test'
GO
4,验证数据表级别的cdc是否开启
执行下面的sql可以验证库名为ZEE下的表Test是否开启:(要注意的是相同库下不同的架构名称可能会有多个相同的表)
use ZEE
select sys.objects.name as [表对象名称],sys.schemas.name as [架构名称] ,[is_tracked_by_cdc]
from sys.objects,sys.schemas,sys.tables
where sys.objects.type='U'
and sys.objects.schema_id=sys.schemas.schema_id and
sys.objects.name=sys.tables.name and sys.objects.schema_id=sys.tables.schema_id
and sys.objects.name='Test'
order by is_tracked_by_cdc desc
执行结果:is_cdc_enabled等于1是开启(如果等于0代表没有开启)
5,批量开启表的cdc(后面补充)
pipeline设计
1.添加各种组件cdc
参考pipeline:sqlservercdc2mysql
2.SQL server cdc client组件配置要点
CDC选项:一行配置一个表,好处是按需接入
Capture_Instance_Name: 架构名_表名 ,必须要有最好一个表配置一个
Initial_Offset:按表偏移量,可不填
JDBC选项:
主要是配置是连接串:例如下面其中databaseName参数是库名
JDBC Connection String: jdbc:sqlserver://10.130.217.51:28688;databaseName=ZEE
处理多张表
在一个 Pipeline 中处理多张表,可以简化很多开发和维护工作。
- binlog 组件中,写入多个表名,中间用逗号隔开
- JDBC Producer 组件中,用 streamsets 表达式表示表名,写入指定表
存在的缺陷
目前对server2016的CDC 测试来看优点是能拿到增删改的数据,
对于有主键(包括联合主键)还可以很好的支持输出端mysql的增删改
缺陷有以下:
1,对没有主键的表在pipeline流程的输出端mysql,只能进行mysql插入操作
具体的验证方案一:
1, sqlserver2016的源端ZEE库下,创建主键和无主键二种类型的表。然后目标端myql的test库下创建对应的二种类型的表。
2 在sqlserver2016的源端ZEE库下在启动二种类型的表的cdc。
3,在streamset的验证pipeline上配置好二张表的cdc信息,配置可参考pipeline部分.
4, 启动pipeline ,在sqlserver2016的源端ZEE库下做二种类型表的sql操作(insert
update,delete),观察目标端mysql对应的表数据的变化。
具体的验证方案二:
其它生产环境的版本比如2008r2,支持的程度待安装验证
结论:2008版本支持cdc,配置方式与2016一样
出现问题的解决方案:
1,开启某个数据库的CDC功能
USE [ZEE];
GO
EXEC sys.sp_cdc_enable_db;
执行失败, 原因是数据库所有者为Windows用户,
解决:数据库所有者改为“sa”
2,重置某张cdc表,重启pipeline报错
报错信息:DBC_78 - Retries exhausted, giving up after as per stage configuration. First error: com.microsoft.sqlserver.jdbc.SQLServerException: 为过程或函数 cdc.fn_cdc_get_all_changes_ ... 提供的参数数目不足。
报错原因:cdc表重置(先关闭再启动),偏移量字段__$start_lsn重置为空,streamset还是按以前的偏移量读
如何重现:
通命令关闭某张表的cdc,再通过命令启动表的cdc, 注意重置后lsn_time_mapping表(所有cdc表的偏移量映射)的记录仍然存在,被重置的cdc表偏移量记录会被清空。
解决:
编辑文件 /usr/local/streamsets-datacollector/data/runInfo/某个pipline/offset.json
去掉cdc已重置的表的那条偏移量记录再启动pipeline的start.
重置的表会从开始读,其它的表不受影响会从offset.json文件中已保存的最大的那条偏移量读。
其它:如何查找cdc表中的偏移量(示例)
set showplan_all on
go
--通过开启执行计划优化后的查询语句 ,优化后下面这条sql会走索引
SELECT b.[tran_end_time] ,CONVERT(varchar, a.[__$start_lsn], 2) __$start_lsn,
CONVERT(varchar, a.[__$seqval], 2) __$seqval, a.[__$operation]
FROM [ZEE].[cdc].[dbo_sqlservertest_key_CT] a,
[ZEE].[cdc].[lsn_time_mapping] b where a.__$start_lsn = b.start_lsn and
b.[tran_end_time]>'2021-04-14' order by a.[__$start_lsn] desc
set showplan_all off
有了tran_end_time时间可以将各个cdc表抽到一张mysql表中保留一天的数据方便维护
3、SELECT max(CONVERT(varchar, __$start_lsn, 2)) as max_lsn from [ZEE].[cdc].[dbo_sqlservertest_key_CT] 查找最大的偏移量
示例:
SELECT CONVERT(varchar, a.__$start_lsn, 2) as aa, CONVERT(varchar, b.start_lsn, 2) as bb, b.tran_begin_time, a.id,a.city, a.NUM
FROM [ZEE].[cdc].[dbo_sqlservertest_key_CT] a, [ZEE].[cdc].[lsn_time_mapping] b where CONVERT(varchar, a.__$start_lsn, 2) = CONVERT(varchar, b.start_lsn, 2) order by b.tran_begin_time desc