SQLSERVER:源库CDC执行缓慢参数优化

CDC已严重积压+DTS 拉取慢​的场景下,更稳妥、安全的调整是:
EXEC sys.sp_cdc_change_job 
    @job_type = 'capture',
    @maxtrans = 2000,      -- 不要一上来就 5000
    @maxscans = 1,         -- 关键:改成 1
    @continuous = 1;

-- 重启 Job 生效
EXEC sys.sp_cdc_stop_job @job_type = 'capture';
EXEC sys.sp_cdc_start_job @job_type = 'capture';

以上命令执行完成后,查看CDC占用的磁盘空间,如果数值一直在减小,说明参数调整有效果:
查看CDC占用的磁盘空间:
use egshop_xsy
SELECT
SUM(ps.used_page_count) * 8.0 / 1024 AS Total_CDC_Size_MB
FROM sys.dm_db_partition_stats ps
JOIN sys.tables t ON t.object_id = ps.object_id
WHERE t.schema_id = SCHEMA_ID('cdc');
 
核心改动点:@maxscans = 1


二、为什么要这样调?(非常重要)
1.@maxtrans = 2000(而不是 5000)
@maxtrans
每次扫描日志时,最多处理的事务数​
太大 → 单次事务过久 → 锁、日志、TempDB 压力
现状判断:
CDC 已积压 85 GB
DTS 还在慢慢拉
日志文件已经 155 GB
👉 说明 Capture Job 已经在“拼命干活”,不是“干得太少”,而是干得太慢 / 干不完。
✅ 把 @maxtrans从 500 → 2000:
提高吞吐
又不会让单次扫描变成“长事务”
❌ 不建议直接 5000:
容易引发 日志扫描超时
可能加剧 DTS 的查询阻塞


2.@maxscans = 1(这是关键)
很多人会忽略这个参数,但它直接决定 CDC 的行为模式。
@maxscans

每一轮扫描日志的循环次数​
10
默认行为(@maxscans=10):


一轮扫描 → 处理 500 个事务 × 10 次循环
然后再 Sleep → 再下一轮
问题来了:


在你这种 积压严重​ 的情况下
CDC 会在一轮里疯狂扫日志
导致:
ct表写入风暴
DTS 查询 fn_cdc_get_all_changes_*极慢
日志文件无法及时截断


✅ 改成 @maxscans = 1的好处:
每轮只扫一次
立刻让出资源
给 DTS 更多机会去读 ct表
有助于 降低 DTS 延迟
有利于日志截断推进
📌 微软官方 + 阿里云 DTS 最佳实践都推荐:高并发/同步场景下调小 @maxscans
3.@continuous = 1(保持不变 ✅)
这个是对的,表示:
Capture Job 一直运行
不停轮询日志
不要改成 0,否则 CDC 会“停摆”。


三、配套必须一起做的 3 件事(否则调了也没用)
✅ 1. 确认没有长事务(最重要)
DBCC OPENTRAN('egshop_xsy');
如果返回:
oldest active transaction
且 start time 很早(几小时甚至几天)
👉 CDC 永远追不上
👉 DTS 永远慢
➡️ 必须:提交 / 回滚 / Kill 会话


✅ 2. 确认 Capture Job 真的在跑
EXEC sys.sp_cdc_help_jobs;
重点看:
is_enabled = 1
status = 1


✅ 3. Cleanup Job 别“拖后腿”
如果 retention 还是 3 天(4320 分钟),而你现在 85 GB:
EXEC sys.sp_cdc_change_job 
    @job_type = 'cleanup',
    @retention = 1440; -- 改为 1 天
然后在低峰期 手动触发一次清理(见上一轮回答)。


四、调整后怎么验证是否有效?
1看日志重用等待
SELECT log_reuse_wait_desc
FROM sys.databases
WHERE name = 'egshop_xsy';


✅ 从 REPLICATION→ NOTHING/ CHECKPOINT
说明 CDC 开始正常推进


2看 DTS 延迟是否下降
阿里云 DTS 控制台
源端延迟
消费位点 LSN
如果 10–30 分钟内明显下降,说明调整有效。


3看 CDC 内部表增长趋势
SELECT 
    OBJECT_NAME(object_id) AS TableName,
    SUM(used_page_count) * 8 / 1024 AS SizeMB
FROM sys.dm_db_partition_stats
WHERE OBJECT_NAME(object_id) LIKE '%ct%'
GROUP BY object_id;


✅ 增长速度明显放缓 = 成功


五、一句话总结(给你吃颗定心丸)
你现在不是“CDC 干得不够”,而是“CDC 干得太猛、DTS 跟不上、日志卡住了”。
✅ 把 @maxscans降到 1​
✅ @maxtrans控制在 2000 左右​
✅ 清理长事务
✅ 配合 cleanup
这样调整后,DTS 抽取慢的问题大概率会在 30–60 分钟内明显改善。
如果你愿意,可以把 sp_cdc_help_jobs的输出贴出来,我可以帮你算一套完全贴合你机器规格(CPU / 内存 / 磁盘)的最优参数。
分割线
感谢打赏
江西数库信息技术有限公司
YWSOS.COM 平台代运维解决方案
 评论
 发表评论
姓   名:

Powered by AKCMS