在SQL Server 2008版本以前,對錶數據庫的變動監控,咱們一般使用DML觸發器進行監控,把DML操做中的INSERT/UPDATE/DELETE數據記錄下來,可是觸發器的維護比較困難;html
當SQL Server 2008新功能:變動數據捕獲(Change Data Capture,即CDC)出來以後,我發現這正是我想要的,由於我以前使用DML觸發器實現的時候也是把UPDATE操做按照兩條記錄進行記錄的,共同的缺點都是在用戶修改了表結構後,CDC不會自動同步到記錄中,不過CDC也有DDL的監控能夠補充這個缺陷;CDC的優勢就是以異步進程讀取事務日誌進行捕獲數據變動的。sql
(一) 建立一個測試數據庫;數據庫
/******* 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'
(Figure1:數據庫CDC狀態)less
(Figure2:啓用數據庫CDC建立的系統表)異步
(Figure3:數據庫CDC狀態)測試
(Figure4:添加新用戶和架構)spa
開啓數據庫的CDC以後,分別在用戶和架構上建立新的用戶cdc,新的架構cdc;.net
(三) 建立一個測試表,對錶行變動啓用捕獲,爲表[Department]啓用CDC,首先會在系統表中建立[cdc].[dbo_Department_CT],會在Agent中建立兩個做業,cdc.CDC_DB_capture和cdc.CDC_DB_cleanup,啓用表變動捕獲須要開啓SQL Server Agent服務,否則會報錯。每對一個表啓用捕獲就會生成一個向對應的記錄表。3d
/******* 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'
(Figure5:提示信息)
(Figure6:新增長的系統表)
(Figure7:生成的捕獲和清理做業)
(Figure8:表的CDC狀態)
(Figure9:多了個數據庫角色)
(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
(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 包含新值和舊值 */
(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'
(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
(Figure13:數據庫做業信息)
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 範圍內的全部更改。 對於由更新操做致使的更改,此選項將返回在更新以前包含列值的行和更新以後包含列值的行。
SQL Server 2008中新增的變動數據捕獲(CDC)和更改跟蹤
使用SQLServer 2008的CDC功能實現數據變動捕獲(原地址)
SQL Server 2008中的CDC(Change Data Capture)功能使用及釋疑
cdc.fn_cdc_get_all_changes_<捕獲實例> (Transact-SQL)
ALTER AUTHORIZATION (Transact-SQL)
sys.sp_cdc_change_job(中英文對譯)