SQL Server Integration Services (SSIS):完全指南
2026-08-07
2026-08-07
2026-08-04
2026-08-04
SQL Server 变更数据捕获(CDC)是一个内置功能,用于记录数据库表上的 INSERT、UPDATE 和 DELETE 操作。它从事务日志中异步捕获变更,并将其存储在变更表中,使应用程序能够访问增量数据而无需扫描整个表。
对于数据工程师和 DBA 来说,SQL Server 中的 CDC 通过仅跟踪已变更的数据,为数据同步、ETL 工作流和分析提供了一种高效的方式。
SQL Server CDC 捕获三种主要类型的数据变更:
例如,当某位员工的薪资从 75,000 美元变更为 80,000 美元时,CDC 会在变更表中记录更新前后的值。这使得下游系统能够识别发生了什么变更以及变更发生的时间。
了解 SQL Server CDC 的工作原理有助于更轻松地配置和管理它。启用 CDC 后,数据变更通过一个四步过程异步捕获,对正常数据库操作的影响极小。

每当数据被插入、更新或删除时,SQL Server 都会将该操作记录到事务日志中。CDC 不是监控用户查询或使用触发器,而是读取这些现有的日志记录来捕获数据变更。
启用 CDC 后,SQL Server 会创建一个捕获作业,持续扫描事务日志以查找已提交的变更。它在后台运行,异步处理变更,对写入性能的影响极小。
捕获作业将检测到的变更写入 cdc 架构下的系统管理变更表中,例如 cdc.dbo_TableName_CT。每条记录都包含变更数据以及日志序列号(LSN)和操作类型等元数据。
应用程序、ETL 工具和复制服务可以从 CDC 变更表中检索增量变更。Microsoft 建议使用内置的 CDC 函数(如 fn_cdc_get_all_changes 和 fn_cdc_get_net_changes),而不是直接查询变更表。
启用 SQL Server 变更数据捕获(CDC)涉及三个步骤:验证前提条件、在数据库级别启用 CDC,然后为您要跟踪的表启用 CDC。
在启用 CDC 之前,请确保您的环境满足以下要求:
db_owner 权限或 sysadmin 服务器级权限。net changes 函数,则需要主键或唯一索引。在您可以跟踪表变更之前,请先为数据库启用 CDC。
USE YourDatabaseName;
GO
-- 检查是否已启用 CDC
SELECT name, is_cdc_enabled
FROM sys.databases
WHERE name = DB_NAME();
-- 启用 CDC
EXEC sys.sp_cdc_enable_db;
GO
为数据库启用 CDC 后,您可以为各个表启用它。
USE YourDatabaseName;
USE YourDatabaseName;
GO
-- 如果不存在则创建示例表
IF OBJECT_ID('dbo.Employees', 'U') IS NULL
BEGIN
CREATE TABLE dbo.Employees (
EmployeeID INT IDENTITY(1,1) PRIMARY KEY,
FirstName VARCHAR(50),
LastName VARCHAR(50),
Salary DECIMAL(18,2),
LastModified DATETIME DEFAULT GETDATE()
);
END;
GO
-- 在表上启用 CDC
EXEC sys.sp_cdc_enable_table
@source_schema = N'dbo',
@source_name = N'Employees',
@role_name = NULL,
@supports_net_changes = 1;
GO
运行以下查询以验证 CDC 是否已成功启用。
-- 验证表是否被 CDC 跟踪
SELECT name, is_tracked_by_cdc
FROM sys.tables
WHERE name = 'Employees';
-- 验证捕获和清理作业是否存在
EXEC sys.sp_cdc_help_jobs;
如果 CDC 启用成功,is_tracked_by_cdc 返回 1,并且捕获和清理作业都会列出。
SQL Server 提供了用于查询捕获的变更的内置函数,而不是直接访问 CDC 变更表。
了解日志序列号(LSN)
SQL Server 中的每个事务都由一个日志序列号(LSN)标识。要在特定时间范围内查询变更,请首先将开始和结束时间戳转换为 LSN 值。
DECLARE @from_lsn BINARY(10), @to_lsn BINARY(10);
-- 将时间范围映射到 LSN 值
SET @from_lsn = sys.fn_cdc_map_time_to_lsn(
'smallest greater than or equal',
'2026-07-15 08:00:00'
);
SET @to_lsn = sys.fn_cdc_map_time_to_lsn(
'largest less than or equal',
'2026-07-15 17:00:00'
);
使用 fn_cdc_get_all_changes
使用 fn_cdc_get_all_changes 返回 LSN 范围内的每个 INSERT、UPDATE 和 DELETE 操作。此函数通常用于审计和详细的变更跟踪。
SELECT *
FROM cdc.fn_cdc_get_all_changes_dbo_Employees(
@from_lsn,
@to_lsn,
'all'
);
使用 fn_cdc_get_net_changes
当您只需要所选 LSN 范围内每个修改行的最终状态时,请使用 fn_cdc_get_net_changes。
SELECT *
FROM cdc.fn_cdc_get_net_changes_dbo_Employees(
@from_lsn,
@to_lsn,
'all'
);
了解 CDC 操作代码
__$operation 列标识 CDC 函数返回的变更类型。
| 操作代码 | 操作类型 | 描述 |
|---|---|---|
| 1 | 删除 | 行已被删除。 |
| 2 | 插入 | 已插入新行。 |
| 3 | 更新(之前) | 更新前的行值。 |
| 4 | 更新(之后) | 更新后的行值。 |
SQL Server 提供了两个用于跟踪数据变更的内置功能:变更数据捕获(CDC)和更改跟踪(CT)。虽然两者都记录数据修改,但它们的目的不同。CDC 捕获详细的变更历史,而更改跟踪仅标识哪些行发生了变更。
| 功能 | 变更数据捕获(CDC) | 更改跟踪(CT) |
|---|---|---|
| 主要目的 | 捕获详细的变更历史,用于审计和 ETL。 | 跟踪变更的行,用于数据同步。 |
| 捕获的数据 | 存储完整的变更行。 | 仅存储主键和变更信息。 |
| 新旧值 | 捕获变更前后的值。 | 不存储历史值。 |
| 性能影响 | 异步运行,对事务影响最小。 | 在事务期间跟踪变更,开销较低。 |
| 存储 | 存储使用量较高。 | 存储使用量较低。 |
| 最佳适用场景 | ETL、分析、审计和数据复制。 | 应用程序和客户端同步。 |
| 审计能力 | 支持完整的变更历史。 | 不支持历史审计。 |
简而言之,当您需要详细的变更历史时选择 CDC,当您只需要高效识别变更的行时选择更改跟踪。
何时应选择 CDC?
当您需要完整的数据变更历史而不仅仅是最新状态时,请选择 SQL Server CDC。它非常适合 ETL 管道、数据仓库、实时分析和流平台,在这些场景中需要捕获每个 INSERT、UPDATE 和 DELETE。
何时更适合选择更改跟踪?
当您只需要知道自上次同步以来哪些行发生了变更时,请选择更改跟踪。由于它存储的信息比 CDC 少,因此使用更少的存储空间,更适合应用程序与 SQL Server 之间的轻量级同步。
与 CDC 不同,更改跟踪不保留历史更新。如果在同步之前一行被多次更新,只有其最新状态可用。
尽管 SQL Server CDC 是一个强大的功能,但在生产环境中使用之前应考虑其几个限制。
CDC 依赖 SQL Server Agent 来运行捕获和清理作业。如果该服务停止,变更将不再被处理,这可能阻止事务日志被截断并导致其随时间增长。
CDC 将变更数据的副本存储在 cdc 架构下的系统变更表中。在频繁更新或包含大列的数据库中,这些表可能快速增长,因此应规划足够的存储空间。
默认情况下,捕获的变更在清理作业将其移除之前保留 72 小时(3 天)。
如果下游应用程序或 ETL 流程在此期限内未读取变更,数据将被永久删除。您可以增加保留期限,但这也会增加存储使用量。
某些架构变更不会被 CDC 自动处理,可能需要额外配置。
启用和管理 CDC 需要 sysadmin 或 db_owner 权限。启用 CDC 时,可以通过配置门禁角色来限制对捕获数据的访问。
CDC 在 SQL Server Developer、Enterprise 和 Standard 版本中受支持(SQL Server 2016 SP1 及更高版本)。它在 SQL Server Express 中不可用。
CDC 是为在单个数据库内跟踪变更而构建的,而不是为实时同步两个数据库而设计的。其捕获作业按计划运行,这意味着变更发生与该变更出现在变更表中之间始终存在一些延迟。对于审计或 ETL 管道来说,这种延迟是可以接受的。但对于灾难恢复、跨数据库同步或需要新鲜数据的报告系统来说,它就成了一个限制。
这就是像 i2Stream 这样的专用数据库复制工具发挥作用的地方。i2Stream 不是定期将变更捕获到同一数据库中的表中,而是直接读取事务日志并将这些变更实时流式传输到目标数据库,无论该目标位于同一平台还是完全不同的平台。
i2Stream 提供了多项功能,正好填补了 CDC 留下的空白:
如果您的使用场景更接近于持续同步两个数据库——无论是用于灾难恢复、迁移还是自动故障切换——i2Stream 扩展了 CDC 的功能,将定期变更捕获转变为持续的跨平台复制。
Info2Soft 还根据您要保护的内容提供其他数据韧性解决方案。i2Backup 处理跨数据库、VM 和物理服务器的集中式备份,而 i2Availability 提供专为高可用性故障切换场景构建的实时复制。
遵循一些最佳实践有助于提高生产环境中 SQL Server CDC 的性能、可靠性和可维护性。
@captured_column_list 参数来减小变更表的大小。EXEC sys.sp_cdc_change_job
@job_type = N'cleanup',
@retention = 5760;
GO
EXEC sys.sp_cdc_stop_job @job_type = N'cleanup';
EXEC sys.sp_cdc_start_job @job_type = N'cleanup';
GO
fn_cdc_get_all_changes 和 fn_cdc_get_net_changes。这些函数提供了一种在指定的 LSN 范围内检索变更的一致方式。SELECT
session_id,
start_time,
end_time,
duration,
scan_phase,
log_record_count,
latency
FROM sys.dm_cdc_log_scan_sessions;
如果捕获延迟持续增加,请考虑调整捕获作业的 @maxtrans 或 @maxscans 设置,以便在每次扫描中处理更多事务。
变更数据捕获为 SQL Server 提供了一种内置方式来跟踪行级变更,用于审计、ETL 和增量同步,而无需构建自定义触发器或时间戳逻辑。启用它只需几个步骤,但要充分利用它,需要了解其保留限制、存储影响以及它与更改跟踪的区别。
如果您的需求超出了捕获变更的范围,而是需要在不同平台之间持续同步数据库,那么值得进一步探索像 英方软件 的 i2Stream 这样的实时复制工具。
公告
邮件
销售