SQL Server 變更數據捕獲(CDC)監控表數據


一.本文所涉及的內容(Contents)

  1. 本文所涉及的內容(Contents)
  2. 背景(Contexts)
  3. 實現過程(Realization)
  4. 補充說明(Addon)
  5. 參考文獻(References)

二.背景(Contexts)

  在SQL Server 2008版本之前,對表數據庫的變更監控,我們通常使用DML觸發器進行監控,把DML操作中的INSERT/UPDATE/DELETE數據記錄下來,但是觸發器的維護比較困難;

  當SQL Server 2008新功能:變更數據捕獲(Change Data Capture,即CDC)出來之后,我發現這正是我想要的,因為我之前使用DML觸發器實現的時候也是把UPDATE操作按照兩條記錄進行記錄的,共同的缺點都是在用戶修改了表結構后,CDC不會自動同步到記錄中,不過CDC也有DDL的監控可以補充這個缺陷;CDC的優點就是以異步進程讀取事務日志進行捕獲數據變更的。

三.實現過程(Realization)

(一) 創建一個測試數據庫;

/******* Step1:創建示例數據庫*******/
USE master
GO
IF EXISTS(SELECT name FROM sys.databases WHERE name = 'CDC_DB')
DROP DATABASE CDC_DB
GO
CREATE DATABASE CDC_DB
GO

 

(二) 在開啟數據庫的CDC之前先查詢一下狀態,is_cdc_enabled值為0表示沒有開啟,1表示開啟,當為數據庫[CDC_DB]啟用了CDC之后,在CDC_DB系統表中會出現下圖Figure2所示的6個表;

/******* Step2:開啟數據庫CDC *******/
--查看數據庫是否啟用CDC
SELECT name,is_cdc_enabled FROM sys.databases WHERE name = 'CDC_DB'

--啟用數據庫CDC
USE CDC_DB
GO
EXECUTE sys.sp_cdc_enable_db;
GO

--檢查啟用是否成功
SELECT is_cdc_enabled,CASE WHEN is_cdc_enabled=0 THEN 'CDC功能禁用' ELSE 'CDC功能啟用' END 描述
FROM sys.databases
WHERE NAME = 'CDC_DB'

wps_clip_image-1021

(Figure1:數據庫CDC狀態)

wps_clip_image-29510

(Figure2:啟用數據庫CDC創建的系統表)

wps_clip_image-13454

(Figure3:數據庫CDC狀態)

wps_clip_image-14649

(Figure4:添加新用戶和架構)

開啟數據庫的CDC之后,分別在用戶和架構上創建新的用戶cdc,新的架構cdc;

 

(三) 創建一個測試表,對表行變更啟用捕獲,為表[Department]啟用CDC,首先會在系統表中創建[cdc].[dbo_Department_CT],會在Agent中創建兩個作業,cdc.CDC_DB_capture和cdc.CDC_DB_cleanup,啟用表變更捕獲需要開啟SQL Server Agent服務,不然會報錯。每對一個表啟用捕獲就會生成一個向對應的記錄表。

/******* Step3:對表啟用變更捕獲*******/
--創建測試表
USE CDC_DB
GO
CREATE TABLE [dbo].[Department](
    [DepartmentID] [smallint] IDENTITY(1,1) NOT NULL,
    [Name] [nvarchar](200) NULL,
    [GroupName] [nvarchar](50) NOT NULL,
    [ModifiedDate] [datetime] NOT NULL,
    [AddName] [nvarchar](120) NULL,
 CONSTRAINT [PK_Department_DepartmentID] PRIMARY KEY CLUSTERED 
(
    [DepartmentID] ASC
) ON [PRIMARY]
) ON [PRIMARY]
GO

--對表啟用捕獲
EXEC sys.sp_cdc_enable_table 
    @source_schema= 'dbo',
       @source_name = 'Department',
       @role_name = N'cdc_Admin',
       @capture_instance = DEFAULT,
       @supports_net_changes = 1,
    @index_name = NULL,
    @captured_column_list = NULL,
    @filegroup_name = DEFAULT

--檢查是否成功
SELECT name, is_tracked_by_cdc ,
    CASE WHEN is_tracked_by_cdc = 0 THEN 'CDC功能禁用' ELSE 'CDC功能啟用' END 描述
FROM sys.tables
WHERE OBJECT_ID= OBJECT_ID('dbo.Department')

--返回某個表的變更捕獲配置信息
EXEC sys.sp_cdc_help_change_data_capture 'dbo', 'Department'

wps_clip_image-12260

(Figure5:提示信息)

wps_clip_image-25427

(Figure6:新增加的系統表)

wps_clip_image-21092

(Figure7:生成的捕獲和清理作業)

wps_clip_image-14851

(Figure8:表的CDC狀態)

wps_clip_image-12771

(Figure9:多了個數據庫角色)

wps_clip_image-5760

wps_clip_image-15007

(Figure10:sys.sp_cdc_enable_table配置選項)

上圖深色部分的字段值是在執行sys.sp_cdc_enable_table的時候設置的。

 

(四) 測試插入數據、更新數據、刪除數據,執行完這些DML,我們來觀察下cdc.dbo_Department_CT幫我們記錄些什么?

/******* Step4:測試DML變更捕獲*******/
--測試插入數據
INSERT  INTO dbo.Department(
    Name ,
    GroupName ,
    ModifiedDate
)VALUES('Marketing','Sales and Marketing',GETDATE())

--測試更新數據
UPDATE dbo.Department SET Name = 'Marketing Group',ModifiedDate = GETDATE()
WHERE Name = 'Marketing'

--測試刪除數據
DELETE FROM dbo.Department WHERE Name='Marketing Group'

--查詢捕獲數據
SELECT * FROM cdc.dbo_Department_CT

wps_clip_image-29776

(Figure11:變更記錄表)

對於insert/delete操作,會有對應的一行記錄,而對於update,會有兩行記錄。__$operation列:1 = 刪除、2= 插入、3= 更新(舊值)、4= 更新(新值);

 

(五) 啟用CDC之后,你怎么從中獲取到數據呢?通過數據我們可以對數據進行恢復;

/******* Step6:使用LSN 查看CDC記錄*******/
--http://msdn.microsoft.com/zh-cn/library/bb500137%28v=sql.100%29.aspx
SELECT sys.fn_cdc_map_time_to_lsn
('smallest greater than or equal', '2013-07-24 09:00:30') AS BeginLSN

SELECT sys.fn_cdc_map_time_to_lsn
('largest less than or equal', '2013-07-24 23:59:59') AS EndLSN


/******* 查看某時間段所有CDC記錄*******/
DECLARE @FromLSN binary(10) =
sys.fn_cdc_map_time_to_lsn
('smallest greater than or equal' , '2013-06-23 09:00:30')

DECLARE @ToLSN binary(10) =
sys.fn_cdc_map_time_to_lsn
('largest less than or equal' , '2013-07-26 23:59:59')

SELECT CASE [__$operation]
WHEN 1 THEN 'DELETE'
WHEN 2 THEN 'INSERT'
WHEN 3 THEN 'Before UPDATE'
WHEN 4 THEN 'After UPDATE'
END Operation,[__$operation],[__$update_mask],DepartmentId,Name,GroupName,ModifiedDate,AddName
FROM [cdc].[fn_cdc_get_all_changes_dbo_Department]
(@FromLSN, @ToLSN,  N'all update old')
/*
all 其中的update,只包含新值
all update old 包含新值和舊值
*/

wps_clip_image-16708

(Figure15:通過時間獲取LSN更新)

 

(六) CDC的維護

/******* Step5:維護CDC *******/
--返回所有表的變更捕獲配置信息
EXECUTE sys.sp_cdc_help_change_data_capture;

--返回某個表的變更捕獲配置信息
EXEC sys.sp_cdc_help_change_data_capture 'dbo', 'Department'

--查看對某個表的哪些列做了捕獲監控,使用上面返回的capture_instance列值
EXEC sys.sp_cdc_get_captured_columns
@capture_instance = 'dbo_Department'

wps_clip_image-26559

(Figure12:監控表字段信息)

由於sys.sp_cdc_enable_table 的參數:@captured_column_list = NULL,所以dbo.Department表的所有字段都進行監控了,如果你只關心某些字段,強烈建議在創建捕獲的時候設置這個屬性;

--所有數據庫CDC Job信息
SELECT B.name,A.* FROM msdb.dbo.cdc_jobs AS A
LEFT JOIN sys.databases AS B
ON A.database_id = B.database_id

--當前數據庫CDC Job信息
EXEC sp_cdc_help_jobs

wps_clip_image-6647

(Figure13:數據庫作業信息)

四.補充說明(Addon)

  SQL Server記錄數據變更有四種方法:觸發器、Output子句、變更數據捕獲(Change Data Capture 即CDC)功能、同步更改跟蹤。其中后兩個為SQL Server 2008所新增。

CDC功能主要捕獲SQLServer指定表的增刪改操作;

CDC除了捕獲數據變更之外,還能捕獲DDL操作的變化;

無法對系統數據庫和分發數據庫啟用該功能。且執行者需要用sysadmin角色權限;

cdc.<capture_instance>_CT   可以看到,這樣命名的表,是用於記錄源表更改的表。對於insert/delete操作,會有對應的一行記錄,而對於update,會有兩行記錄;

對於__$start_lsn列:由於更改是來源與數據庫的事務日志,所以這里會保存其事務日志的開始序列號(LSN);

對於__$end_lsn列:

對於__$seqval列:

對於__$operation列:1 = 刪除、2= 插入、3= 更新(舊值)、4= 更新(新值);

對於__$update_mask列:

恢復模式為簡單模式一樣可以進行CDC;

雖然能捕獲到數據變更,但是沒有辦法找到是誰更新的?

能使用這個做回滾嘛?備份的另外一種路徑?對表更新不頻繁的情況下?

如果是添加或者刪除了某些字段DDL,那么創建的CDC表並沒有做更改,那新字段的數據怎么捕獲呢?修改字段長度等這些操作同樣會一起修改CDC對應的表字段;

sys.sp_cdc_enable_table 的@role_name參數,是指角色-數據庫角色,這個有什么用呢?應用程序角色又有什么用呢?

cdc.Person_Contact_CT這名字中CT代表什么意思呢?Capture Table?(用戶.架構_表_CT)

SQL Server 自啟動了兩個job,一個捕獲,一個清除,注意清除是默認凌晨2點,清除72小時以上的數據。如果同一數據庫的表中CDC已經啟用,不會重建job。

all

返回指定 LSN 范圍內的所有更改。 對於由更新操作導致的更改,此選項只返回在應用更新之后包含新值的行。

all update old

返回指定 LSN 范圍內的所有更改。 對於由更新操作導致的更改,此選項將返回在更新之前包含列值的行和更新之后包含列值的行。

更改數據捕獲存儲過程 (Transact-SQL)

關於變更數據捕獲 (SQL Server)

變更數據捕獲表 (Transact-SQL)

五.參考文獻(References)

SQL Server 2008中新增的變更數據捕獲(CDC)和更改跟蹤

變更數據捕獲

變更數據捕獲基本知識

跟蹤數據更改 (SQL Server)

關於變更數據捕獲 (SQL Server)

使用SQLServer 2008的CDC功能實現數據變更捕獲原地址

SQL Server 2008中的CDC(Change Data Capture)功能使用及釋疑

SQL Server 2008 的CDC功能

關於CDC功能的答疑

cdc.fn_cdc_get_all_changes_<捕獲實例> (Transact-SQL)

ALTER AUTHORIZATION (Transact-SQL)

sys.sp_cdc_change_job(中英文對譯)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM