SQL Server CDC 能放到备库读吗?Always On 可读副本同步优化实践
之前我们谈了 Oracle 备机同步,而 SQL Server 作为源端时也存在同样的问题:数据同步会不会增加主库压力、账号权限能不能最小化、已有 Always On 高可用架构能不能复用。今天这篇文章就来聊聊这个话题。
SQL Server CDC 的增量数据由 SQL Server 事务日志进入捕获流程,再写入 CDC 变更表。同步任务在增量阶段读取 CDC 变更表和相关元数据。
对已经部署 Always On 的环境,可以将这部分操作放到可读副本,让主库继续专注业务写入和 CDC 捕获;同步账号只需要读取角色,从而降低对核心库的权限和性能影响。
SQL Server CDC 增量读取原理
SQL Server CDC 的增量读取入口不是业务表本身,而是启用 CDC 后生成的 capture instance 和对应的 CDC 变更表。
每个启用 CDC 的业务表,都会对应一张 CDC 变更表,命名通常为 cdc.<capture_instance>_CT。业务表发生 INSERT、UPDATE、DELETE 后,变更会先写入 SQL Server 事务日志,再由 SQL Server Agent 的 CDC capture job 捕获,并写入对应的 CDC 变更表。

同步任务消费增量数据时,主要读取 cdc schema 下的几类对象:cdc.<capture_instance>_CT 存放业务表 的 DML 变更,是最核心的数据来源;cdc.change_tables 记录 capture instance、源表、起始 LSN 等信息,用于识别 CDC 表和可读范围;cdc.captured_columns、cdc.index_columns、cdc.ddl_history 等元数据,则用于识别捕获列、索引列和 DDL 历史。
其中,_CT 表中的每条记录除了业务字段外,还包含几类关键 CDC 字段:
__$start_lsn:变更所属事务的提交 LSN,是增量推进的主要位置。__$seqval:同一 LSN 下的操作序列,用于区分多条变更的先后顺序。__$operation:操作类型,1 表示删除,2 表示插入,3 表示更新前镜像,4 表示更新后镜像。__$update_mask:标识 UPDATE 涉及的列。
因此,SQL Server CDC 增量读取的核心,是按照 __$start_lsn、__$seqval、__$operation 等字段顺序消费 _CT 表中的变更记录,并将 INSERT、DELETE、UPDATE 前后镜像转换为下游可以处理的变更事件。
Always On 备库 CDC 原理
在 Always On 场景下,SQL Server CDC 的捕获仍由主副本完成。业务 DML 写入事务日志后,SQL Server Agent 的 capture job 从日志中捕获变更,并写入主副本上的 CDC 变更表;cleanup job 按配置的保留时间清理历史变更。

