數據源
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