目录标题
(SQL Server 在 Docker 中运行 + CDC 启用 + 遇到 Non-yielding Scheduler
报错 + 官方建议)整理的一份完整笔记,可用于部署或问题排查参考。
📘 SQL Server in Docker 启用 CDC 时的性能优化与问题排查笔记
🧨 问题描述
在 SQL Server 2019 (Docker 容器中) 启用 CDC(Change Data Capture) 后,可能出现以下错误:
Non-yielding Scheduler
🚨 错误含义
- 表示某个线程在 SQL Server 内部 长时间占用 CPU 而没有“让出”给其他线程。
- 通常是 死循环、资源阻塞、或调度器被卡死 引起的严重错误。
📌 原因分析
原因 | 说明 |
---|---|
🧠 CDC 高并发 | CDC 捕获变更数据,频繁访问系统表(如 cdc.lsn_time_mapping ),易导致线程阻塞 |
🐳 容器资源限制 | Docker 中未分配足够 CPU 或内存,SQL Server 无法有效调度线程 |
🔄 Debezium 拉数据压力大 | Debezium connector 拉取 CDC 表时,可能增加负载或造成长时间锁定 |
⚙️ Linux I/O 缓存机制 | 写入数据未直接落盘,可能影响 CDC 的事务一致性和性能 |
✅ 官方优化建议
1. 🧾 使用 mssql.conf
启用优化配置
创建配置文件 mssql.conf
:
[traceflag]
traceflag0 = 3979
[control]
writethrough = 1
alternatewritethrough = 0
参数说明:
参数 | 含义 |
---|---|
traceflag0 = 3979 | 禁用轻量级查询资源治理,避免 scheduler 误判或干扰 |
writethrough = 1 | 使用同步写盘(write-through)策略,提升数据一致性 |
alternatewritethrough = 0 | 禁用备用写策略,避免 I/O 缓存影响数据可靠性 |
2. 🧠 调整容器资源(避免被杀或调度器卡死)
运行容器时添加合理的资源限制:
docker run -e 'ACCEPT_EULA=Y' -e 'SA_PASSWORD=YourStrong@Passw0rd' \
-v /path/to/mssql.conf:/var/opt/mssql/mssql.conf \
--cpus="2.0" \
--memory="4g" \
-p 1433:1433 \
mcr.microsoft.com/mssql/server:2019-latest
✅ 建议:
- 至少 2 个 CPU(SQL Server 多线程调度依赖于多个 scheduler)
- 至少 4GB 内存(CDC 和 Debezium 都有缓存需求)
- 使用
cgroup
限制时,需检查 SQL Server 是否正确识别 CPU 数
3. 🔄 调整 Debezium Connector 设置
Debezium 拉 CDC 数据的配置建议如下:
参数 | 建议 |
---|---|
poll.interval.ms | 5000 (单位 ms,避免频繁轮询) |
max.batch.size | 100~500 (限制单批拉取记录数量) |
max.queue.size | 1000~5000 (避免堆积过多记录) |
📚 参考:Debezium 配置参数
🔍 故障排查方法
检查容器是否因内存或 CPU 被杀死:
kubectl describe pod <pod-name>
# 或
docker inspect <container-id>
重点查找:
Last State: Terminated
Reason: OOMKilled
检查 SQL Server 错误日志
/var/opt/mssql/log/errorlog
搜索关键字:
non-yielding
scheduler
memory pressure
🧱 推荐部署策略总结
项目 | 推荐值 |
---|---|
CPU 核心数 | 至少 2 核 |
内存限制 | 至少 4GB |
CDC 表负载 | 避免大事务、频繁更新表 |
Debezium 参数 | 调整 poll/batch 阈值,减少系统压力 |
配置文件 | 使用 mssql.conf 启用官方建议优化参数 |
如需部署在 Kubernetes,也可加挂 mssql.conf
为 ConfigMap
,并通过 volumeMount 注入 SQL Server 容器。