Change data capture (CDC) provides an easy and high-performing way to capture changes in a set of tables. In this article we offer useful examples while pointing out some of the pitfalls that we have come across while working with the CDC. There are many ways to tune the performance of change data capture. Understanding workload characteristics, system I/O usage, and allowable latency is key to tuning change data capture performance without negatively impacting the base workload. Tuning the scan job parameters, sys.sp_cdc_enable_table parameters can significantly improve change data capture performance under load.
Change Data Capture Parameters
Recommendation – 1
If change data capture with default parameters cannot keep up with the workload and latency becomes too high, you can increase maxscans and/or maxtrans by a factor of 10, or you can reduce pollinginterval to 1. If your latency decreases but is still too high, you can further increase maxtrans, but monitor the performance of your workload, latency and performance of queries to the change tables closely. On a system where change data capture can fully keep up with the workload, latency should not be significantly higher than the polling interval, and it should not increase over time.
Recommendation – 2
Always limit the list of columns captured by change data capture to only the columns you really need to track by specifying the @captured_column_list parameter in sys.sp_cdc_enable_table. When enabling CDC on a table, consider what data elements you are actually interested in capturing the changes for over time. By specifying just the columns you need you can improve performance.
We have found that the decreased number of columns captured made a huge difference in overall change data capture performance.
Recommendation – 3
The @supports_net_changes parameter in sys.sp_cdc_enable_table can have significant influence on change data capture performance. When @supports_net_changes is set to 1, an additional non-clustered index will be created on the change table and the net changes query function will be created. Because this index needs to be maintained, we found that enabling net changes can have negative impact on change data capture performance. Especially if change data capture is just able to keep up with a workload, the additional load that is incurred by maintaining the additional index to support net changes queries can be enough to prevent change data capture from keeping up with the workload.
If you do not require support for net changes, set @supports_net_changes to 0. If you do require querying for net changes but change data capture latency grows too big, it can be worthwhile to turn support for net changes off and do the net change detection later in a staging database.
Workload Behavior
Recommendation – 1
For planning a change data capture solution, workloads characteristics are very important. The main factors to consider are INSERT/DELETE vs. UPDATE, and whether the DML operations impact one row per transaction vs. many.
For change data capture, one INSERT only creates one row in the change table. One UPDATE, however, inserts two rows in the change table.
A common scenario in applications is that a row is inserted to a table and then immediately updated to fill missing fields. This can happen in the application or by utilizing an INSERT trigger that looks for missing fields and then updates them if necessary. This will result in three rows instead of one row that needed to be written to the change table for each insert to the original table.
The bottom line is that try to avoid scenarios where a row needs to be updated immediately after insert. And also try to avoid using change data capture to capture changes to tables that have frequent large update transactions.
Cleanup
Recommendation – 1
The cleanup job is initiated by running the parameter less stored procedure sp_MScdc_cleanup_job. This stored procedure starts by extracting the configured retention and threshold values for the cleanup job from msdb.dbo.cdc_jobs. The configurable threshold value derives the maximum number of delete entries that can be deleted using a single statement on clean-up.
Notice that especially with big thresholds, a lock escalation on change tables can happen. This could degrade the application response time, and it could increase the latency of the change data capture scan job. If possible, run cleanup when there is no other workload active or during the off-peak time. Test increasing the threshold parameter until you find a sweet spot for your workload.
Storage
Recommendation – 1
One of the most important things to watch out for with change data capture is the transaction log I/O subsystem. As stated earlier, log file I/O significantly grows when change data capture is enabled in a database. In addition to that, log records stay active until change data capture has processed them. This means that especially in environments where a large latency builds up, the log file can grow significantly because the log space cannot be reused as long as the change data capture scan job has not processed the log records, even in simple recovery model, or even after a log backup in full recovery model.
It should be noted that change data capture works with all recovery models. But when change data capture is enabled, operations that would normally be minimally logged in simple or bulk-logged recovery models are fully logged to enable change data capture to capture all changes.
Be aware also that when a log disk becomes full, you cannot shrink the log file by backing it up and manually shrinking it until change data capture has processed all transactions. But change data capture cannot process the transactions when the log disk is full, because change data capture writes to change tables are logged operations. In this case, the easiest way to recover from this situation is to temporarily add another log file on a different disk.
When planning change data capture architecture, take a significant increase in log size and log volume I/O operations into account. Depending on the amount of data captured by change data capture and the time change data capture needs to catch up with changes, the log file size can grow to 200-300% of the original size, in some cases even more. Size the log file accordingly. Make sure that the growth in log file size does not result in a completely full log disk.
Recommendation – 2
In general there will be no difference in having the change table on the same file group as the application table and having them on different file groups. This might be different when the data files are located on an I/O subsystem that is already under heavy load. In this case, putting change tables in a file group that is located on a different set of physical disks can improve change data capture performance.
To keep the PRIMARY file group small and to have a clear distinction between the application data and the change data, you should consider specifying @filegroup_name in sys.sp_cdc_enable_table as a different file group than PRIMARY.
Recommendation – 3
In addition to the change tables, the table cdc.lsn_time_mapping can also grow to a significant size and become a target of many I/O operations. This table is created on the default file group when sys.sp_cdc_enble_db is executed on a database.
Consider changing the default file group for the database before you execute sys.sp_cdc_enble_db, so that change data capture metadata and especially cdc.lsn_time_mapping are located on a different file group than PRIMARY. You can change the default file group back after the change data capture metadata tables are created.
Change data capture provides an easy and high-performing way to capture changes in a set of tables. There are many ways to tune the performance of change data capture. Understanding workload characteristics, system I/O usage, and allowable latency is key to tuning change data capture performance without negatively impacting the base workload. Tuning the scan job parameters, sys.sp_cdc_enable_table parameters can significantly improve change data capture performance under load.
References
https://technet.microsoft.com/en-us/library/bb522475(v=sql.105).aspx
https://technet.microsoft.com/en-us/library/cc645885(v=sql.105).aspx
https://docs.microsoft.com/en-us/sql/relational-databases/system-tables/dbo-cdc-jobs-transact-sql
https://docs.microsoft.com/en-us/sql/relational-databases/system-tables/cdc-lsn-time-mapping-transact-sql
https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sys-sp-cdc-enable-db-transact-sql