1. 问题现象描述
在 SQL Server 监控过程中,通过执行系统存储过程 sp_replcounters 发现,未配置任何事务复制(Transactional Replication)发布的数据库 db1 出现了异常的事务积压。
具体指标如下:
- replicated transactions(待复制事务数):
11 - replication rate trans/sec(复制速率):
0 - replication latency (sec)(复制延迟):
0
在对象资源管理器(Object Explorer)中确认该数据库没有配置任何本地发布,但日志中仍有 11 个事务被标记为"等待投递"。
2. 根因分析(CDC 与复制的底层共享机制)
在 SQL Server 中,变更数据捕获(CDC, Change Data Capture)与事务复制共享相同的底层日志读取架构。
2.1 日志标记机制
当数据库启用 CDC 后,被捕获表的任何 DML 操作(INSERT、UPDATE、DELETE)在事务日志中使用的标记,与事务复制使用的标记完全相同。因此,sp_replcounters 存储过程不仅可以监控复制,也同样会统计到 CDC 待处理的事务。
2.2 故障直接原因
经排查,该数据库开启了 CDC 功能,但负责扫描日志并写入变更表的 SQL Server Agent 作业 cdc.db1_capture(CDC 捕获作业)处于停止(Stopped)状态。
由于作业未运行,这 11 个事务无法被正常读取和推进,从而永久滞留在日志中,导致 sp_replcounters 计数器出现积压。
3. 解决过程与验证
针对此问题,采取了以下步骤进行恢复:
步骤一:状态确认
执行以下语句确认数据库确实启用了 CDC 功能:
SELECT name, is_cdc_enabled
FROM sys.databases
WHERE name = 'db1';
-- 返回结果中 is_cdc_enabled 为 1
步骤二:定位并重启作业
- 打开 SQL Server Agent(SQL Server 代理) -> Jobs(作业)。
- 找到对应的捕获作业:
cdc.db1_capture。 - 右键点击该作业,选择 Start Job at Step...(在步骤处启动作业) 重新将其拉起。
步骤三:结果验证
作业重新进入"正在运行"状态后,再次执行 sp_replcounters。此时 CDC 捕获作业已成功读取并处理了积压的日志,replicated transactions 计数顺利清零(变为 0),问题得到圆满解决。
4. 运维建议与预防措施
为防止此类因 CDC 作业停止导致事务日志无法截断或堆积的问题再次发生,建议实施以下运维措施:
- 配置作业失败警报:在 SQL Server Agent 中为
cdc.db1_capture作业配置操作员警报(Alerts/Notifications),一旦作业异常停止,立即触发邮件通知。 - 作业自动重启机制:在作业属性的"高级"设置中,配置"如果作业失败,则在 X 分钟后重试",提高作业的自愈能力。
- 定期监控日志截断状态:定期检查
sys.databases中的log_reuse_wait_desc。如果其值显示为REPLICATION,且数据库并未配置复制,应第一时间排查 CDC 捕获作业的状态。