Reading Time: 9 minutesHello everybody!
In this post, I will show you how to monitor and audit data changes to tables using Change Data Capture (CDC) in SQL Server. I had already written the post SQL Server - How to Create a Data Change History for Your Tables (Audit Logs), which uses the table triggers feature to accomplish this task, but would like to show a more robust (and less manual) solution, which has been available since SQL Server 2008 (Enterprise, Developer and Trial - Thanks for the tip, Fabio Colli) and as of SQL Server 2016 SP1, it is also available in the Standard edition.
Widely used in tables that change and need audits and change logs, CDC allows you to create a history of data changes made to a table, all automatically and without having to create triggers or anything to that effect. With this great feature we can identify data insertions, changes (data before and after update) and data deleted from the table as well as structure changes (DDL) made to the monitored tables.
Once this feature is enabled on a table, a new mirror table will be created, with the same columns as the original table and some more metadata columns to control the change made to the original table. This new table, which will be created automatically, accepts normal queries (SELECT) on your data. It is noteworthy that monitoring remains active even after restarting the service.
Change Data Capture (CDC) has a low impact on the database because it works through a SQL Agent job (one job for each database that has CDC enabled) that reads the transaction log asynchronously and stores changes in the history table. For this reason, the database recovery model is automatically changed to FULL if it is in SIMPLE.
Which databases have active CDC?
View content
To check which databases in your instance have Change Data Capture (CDC) enabled, you can refer to the system view information.
sys.databases.
|
SELECT [name], is_cdc_enabled FROM sys.databases |
Example:

What tables are being monitored with CDC?
View content
To check which tables in a given database have the CDC feature enabled, simply look up the sys.tables system view, as shown below:
|
SELECT [name], is_tracked_by_cdc FROM sys.tables |
Example:

How to enable CDC on a database (1 Level)
View content
Change Data Capture (CDC) control is done at the database level. To enable CDC, you will use the system Stored Procedure
sys.sp_cdc_enable_db.
Example of use:
|
USE [dirceuresende] GO EXEC sys.sp_cdc_enable_db GO |
Result:

Once CDC is activated on the instance, you can verify that a “cdc” schema will be created in the database in question:

In addition, some system tables were created using the “cdc” scheme:

The tables created by CDC are:
How to enable CDC and monitor table changes (2 Level)
View content
To start table monitoring and start storing data change history (DML) and structure (DDL), you will need to use system SP
sys.sp_cdc_enable_table.
Example of use:
|
USE [dirceuresende] GO EXEC sys.sp_cdc_enable_table @source_schema = N'dbo', @source_name = N'Clientes', @role_name = NULL GO |
Result:

After running SP above, Change Data Capture (CDC) monitoring has been enabled on the desired table. This will create a new table in cdc.schema_tabela_CT format with the same columns as the original table plus some metadata tables for change control.

If you want to track changes to specific columns, not all columns in the table, you can use this syntax:
|
USE [dirceuresende] GO EXEC sys.sp_cdc_enable_table @source_schema = N'dbo', @source_name = N'Clientes', @role_name = NULL, @captured_column_list = '[Id], [Nome], [Teste]' GO |
Now, let's make some changes to the table to see how CDC behaves?
Data Entry

Data update

Data Removal

Truncating Table Data
As you can see from the print below, once you enable CDC on a table, you will not be able to truncate the data in a table.

Table structure change

As you can see, the column __ $ operation allows us to identify what type of operations are performed in the table, in which the possible values are:
- 1: DELETE
- 2: INSERT
- 3: Value BEFORE UPDATE
- 4: Value AFTER UPDATE
Remember to enable database level CDC before attempting to enable CDC on a table. If you do not do this, you will come across this error message:
Msg 22901, Level 16, State 1, Procedure sp_cdc_enable_table, Line 39 [Batch Start Line 2] The database 'dirceuresende' is not enabled for Change Data Capture. Ensure that the correct database context is set and retry the operation. To report on the databases enabled for Change Data Capture, query the is_cdc_enabled column in the sys.databases catalog view.
What jobs are created by CDC?
View content
As you can see in the topic “How to activate CDC and monitor changes in tables”, when activating CDC in a table, 2 jobs were created automatically (if you activate CDC in other tables, the same 2 jobs will continue to be used, that is, 2 jobs are created per monitored database and not per table):

And these 2 jobs have the following purpose:
How to configure CDC data retention?
View content
A very common doubt of those who want to implement CDC is in relation to data retention. Will this data grow infinitely, without limit?
To that question, the answer is NO. By default, the data will grow until it reaches the default SQL Server limit (4320 minutes = 3 days), which can be a lot or a little, depending on your need.
If you want to change the retention time, you can use the sys.sp_cdc_change_job stored procedure:
|
EXEC sp_cdc_change_job @job_type='cleanup', @retention=10080 -- 7 dias (quantidade de minutos de retenção) |
Reference: https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sys-sp-cdc-change-job-transact-sql
The maximum value for this retention parameter is 52494800 minutes (100 years), but if you want to disable this limit, just disable the cleanup job (cdc.dirceuresende_cleanup)
To view the current retention parameters, use the query below:
|
SELECT [retention], ([retention]) / ((60 * 24)) AS RetentionInDays, * FROM msdb.dbo.cdc_jobs; |
Result:

How to disable CDC on a database (1 Level)
View content
If you want to disable CDC from a database, just use system SP
sys.sp_cdc_disable_db.
Example:
|
USE [dirceuresende] GO EXEC sys.sp_cdc_disable_db GO |
Result:

Please note that when disabling database level CDC, ALL active table level CDC monitoring will also be disabled and historical data will all be lost as well (and you will NOT be changed about the existence of these active table level monitoring). ).
How to disable CDC on a table (2 Level)
View content
To disable CDC from a specific table, you first need to identify the name of the CDC capture instance using SP
sys.sp_cdc_help_change_data_capture or by consulting
cdc.change_tables, then disable monitoring with SP
sys.sp_cdc_disable_table.
Please note that it is possible to disable CDC at the database level even if there are active table level monitoring (and you will NOT be warned about it). At the end of this topic I left some warnings about what happens when you do this. Read until the end!
Identifying the name of the CDC capture instance:
|
USE [dirceuresende] GO EXEC sys.sp_cdc_help_change_data_capture GO SELECT OBJECT_NAME([object_id]), OBJECT_NAME(source_object_id), capture_instance FROM cdc.change_tables |
Result:

Once we have identified the instance name (dbo_Clients), we can now perform the sys.sp_cdc_disable_table to effectively disable CDC in this table:
|
USE [dirceuresende] GO EXEC sys.sp_cdc_disable_table @source_schema = 'dbo', -- sysname @source_name = 'Clientes', -- sysname @capture_instance = 'dbo_Clientes' -- sysname |
Result:

After disabling CDC in the table, you may notice that the monitoring table has been automatically deleted. BE CAREFUL with this, so as not to lose the recorded values and lose your history. If you want to disable CDC but do not intend to lose history, copy the data from the history table to another table before disabling CDC in the table.

Please note that when disabling CDC at the database level, ALL active table-level CDC monitoring will also be disabled and historical data will also be lost as well.
Change Data Capture (CDC) and Backup / Restore Operations
View content
Because CDC is a built-in feature of SQL Server that creates metadata and jobs to perform some activities, operations such as backup / restore may not behave exactly as expected in certain situations.
Restoring the same database in the same instance
In this situation, the restore will be done normally and the CDC will still be up and running after the base is restored. Nothing changes.
Restoring the backup on the same instance but with another database name or another instance
In either case, the CDC will be disabled and the recorded metadata information will be lost, which would be quite bad. To prevent this from happening, you must use the keep_cdc parameter in the restore command.
Example:
|
RESTORE DATABASE [dirceuresende] FROM DISK = 'C:\Backups\dirceuresende.bak' WITH MOVE 'dirceuresende_dados' TO 'C:\Dados\dirceuresende_dados.mdf', MOVE 'dirceuresende_log' TO 'C:\Dados\dirceuresende_log.ldf', KEEP_CDC |
After restore, you will need to run the following commands to recreate CDC jobs:
|
USE [dirceuresende] GO exec sys.sp_cdc_add_job 'capture' GO exec sys.sp_cdc_add_job 'cleanup' GO |
That's it folks!
I hope you enjoyed this post and that it can be helpful to you!
A hug and see you next!
Very well explained article amd easy to understand.
I have a question. I see multiple execution of query ” create procedure [sys].[sp_cdc_scan] ” thru step 2 “cdc.CDCTrack_capture” executing continuously.
is it normal? Why query " create procedure [sys].[sp_cdc_scan] " executing multiple times ?
Well explained article on CDC. I have a question about I am facing an issue at present, might be not an issue.
I see multiple execution of “create procedure [sys].[sp_cdc_scan] ” query whne step 2 “cdc.CDCTrack_capture” executing.
is it really creating SP “[sys].[sp_cdc_scan]” ? If not then why is it appearing as “Create procedure” statement?
Congratulations on the Post! And for Standard Edition (64-bit)?
Hi Victor! As of sql server 2016 SP 1, CDC is available in Standard edition as well.
Prior to this, only in Developer and Enterprise editions or implementing this trigger auditing.
Great post Dirceu. Thanks.
As for the performance of DML operations, is there loss?
Thank you.
For information only:
Change Data Capture is only available in Enterprise, Developer, and Enterprise Evaluation editions.
Good night Dirceu, well this CDC stop, with the table monitoring data load takes up a lot of space?