For the complete documentation index, see llms.txt. This page is also available as Markdown.

SQL Server

CDC source setup for SQL Server

Sling supports Change Data Capture from SQL Server by reading the native CDC change tables. SQL Server CDC is query-based: the SQL Server Agent captures row-level changes from the transaction log into system-managed change tables, and Sling reads those tables on each run using cdc.fn_cdc_get_all_changes_*().

For general CDC concepts, the two-phase process, and all available options, see the Change Capture overview.

Prerequisites

1. Supported Editions

SQL Server CDC is available on Enterprise, Standard (2016 SP1+), and Developer editions. Express edition does not support CDC.

For Azure:

  • Azure SQL Database: CDC is supported on S3 (Standard) tier or higher. Basic/S0/S1/S2 tiers are not recommended.

  • Azure SQL Managed Instance: Full CDC support (same as on-premises).

2. Enable CDC on the Database

Sling automatically enables CDC on the database and on each captured table if the user has sufficient permissions. The steps below are only needed if you prefer to configure CDC manually or if the Sling user does not have db_owner privileges.

USE my_database;
GO
EXEC sys.sp_cdc_enable_db;
GO

Verify CDC is enabled:

SELECT name, is_cdc_enabled FROM sys.databases WHERE name = DB_NAME();
-- is_cdc_enabled should be 1

3. SQL Server Agent Must Be Running

On-premises SQL Server requires SQL Server Agent to be running. When CDC is enabled, SQL Server creates two Agent jobs:

  • cdc.<dbname>_capture — reads the transaction log and populates change tables.

  • cdc.<dbname>_cleanup — purges expired change data (default retention: 3 days).

If Agent is stopped, changes accumulate in the transaction log but are not captured into change tables.

Azure SQL Database does not use SQL Server Agent — it has a built-in CDC scheduler that runs automatically. No action is needed.

4. User Permissions

The Sling user needs:

  • db_owner role membership on the source database (required to enable CDC on tables and query change tables).

If you enable CDC manually on all tables before running Sling, the user only needs SELECT access on both the source tables and the cdc schema change tables. The db_owner role is only required for the sp_cdc_enable_db and sp_cdc_enable_table calls that Sling performs automatically.

5. Enable CDC on Tables (Optional)

Sling automatically enables CDC on each captured table if it is not already enabled. To enable manually:

Verify table-level CDC:

Quick Start

How It Works

Unlike MySQL (binlog streaming) and PostgreSQL (WAL logical replication), SQL Server CDC is query-based:

  1. The SQL Server Agent continuously reads the transaction log and writes row-level changes into CDC change tables (cdc.dbo_<table>_CT).

  2. On each run, Sling queries cdc.fn_cdc_get_all_changes_<capture_instance>() to read changes between the last saved LSN and the current max LSN.

  3. Changes are merged into the target table using the standard CDC merge strategy.

  4. The new LSN position is saved in the state store.

Because CDC is query-based, each run reads all available changes in the LSN range rather than streaming. This means:

  • There is no persistent connection or replication slot (unlike PostgreSQL).

  • The CDC Agent must have time to process the transaction log before Sling can see the changes. There is typically a few seconds of latency between a DML commit and the change appearing in the change table.

Examples

Large Tables with Custom Chunk Size

For very large tables, adjust the chunk size to control memory usage and checkpointing frequency during the initial snapshot.

Time-Bounded Snapshots for Very Large Tables

For tables with hundreds of millions of rows, the initial snapshot can take hours. Use snapshot_run_duration to cap how long each run spends on the snapshot. The next run automatically resumes from the last completed chunk.

High-Throughput Workloads

For tables with heavy write activity, increase run_max_events and run_max_duration so each run captures more changes.

Soft Deletes

Keep deleted rows in the target instead of physically removing them. Deleted rows are marked with _sling_synced_op = 'D'. Useful for audit trails or when downstream queries need to detect deletions.

When a row is deleted in the source, the target row is preserved with _sling_synced_op set to 'D' and _sling_synced_at updated to the current timestamp. A subsequent re-insert of the same primary key restores the row with the appropriate operation type.

Mixed Streams with Per-Stream Overrides

Different tables can have different CDC options.

Replay / Backfill from a Point in Time

If target data becomes inconsistent, you can replay changes from an earlier position. The replay_from value is applied exactly once per unique value.

After the replay run completes, remove or change the replay_from value. Leaving it unchanged has no effect (it is only applied once).

Replay Formats

The replay_from option accepts these SQL Server-specific position formats:

  • RFC 3339 timestamp: 2025-06-01T00:00:00Z — resolved to an LSN using sys.fn_cdc_map_time_to_lsn()

CDC Retention

SQL Server's CDC cleanup job purges change data older than the retention period (default: 3 days / 4320 minutes). Ensure retention is long enough to cover the maximum gap between CDC runs.

Transaction Log Considerations

CDC prevents the transaction log from being truncated until the capture job has processed all changes. If the CDC Agent falls behind (e.g., Agent is stopped or under heavy load), the transaction log can grow significantly.

Monitor transaction log usage:

To tune the capture job throughput:

Troubleshooting

"CDC is not enabled on this database"

Enable CDC on the database. The Sling user must have db_owner role:

"could not enable CDC on <table>"

The Sling user needs db_owner role membership. CDC also requires SQL Server Agent to be running (on-premises) and a supported SQL Server edition.

"sys.fn_cdc_get_max_lsn() returned NULL"

The SQL Server Agent has not completed its first capture scan. Sling retries automatically for up to 30 seconds, but if the error persists:

  1. Verify SQL Server Agent is running.

  2. Manually trigger a scan: EXEC sys.sp_cdc_scan;

  3. Check for errors in the capture job: SELECT * FROM msdb.dbo.cdc_jobs WHERE job_type = 'capture';

"CDC data cleaned up past checkpoint position"

The CDC cleanup job purged change data that Sling hasn't read yet. Increase retention:

Initial snapshot keeps restarting

Ensure SLING_STATE is configured. Without state persistence, Sling cannot track that the snapshot completed and will restart it on every run.

No CDC capture job found warning

SQL Server Agent may not be running. On Windows, start it from SQL Server Configuration Manager or Services. On Linux (Docker), ensure the MSSQL_AGENT_ENABLED environment variable is set:

Schema changes on CDC-enabled tables

When you ALTER TABLE on a CDC-enabled table (e.g., adding a column), the existing CDC capture instance continues tracking the original column set. New columns are not automatically captured.

To capture the new schema, create a second capture instance (SQL Server allows up to 2 per table) and then disable the old one:

A fresh CDC run after re-enabling the capture instance will use the new schema. If Sling's saved checkpoint references the old capture instance, it will automatically detect the change and start from the new instance's minimum LSN.

Last updated

Was this helpful?