DEBUG.WIKI
Evoxt;最高 6.0GHz CPU;高频云服务器 · 免费每周备份;查看配置 →
OnlineSIM:在线接收短信,虚拟号码租用
RackNerd;$21.99/年 · 1GB KVM

Npgsql 复制连接设置无限超时后立即失败,检查 10.0.1 读缓冲路径

LogicalReplicationConnection 在 StartReplication 立即报 TimeoutException,且 WalReceiverTimeout 为 InfiniteTimeSpan 时,核对驱动版本与缓冲超时转换。

LogicalReplicationConnection 已能打开,刚调用 StartReplication 就报 Exception while reading from stream,内层是 Timeout during reading attempt。如果配置了 WalReceiverTimeout = Timeout.InfiniteTimeSpan,并正在使用 Npgsql 10.0.1,应先检查客户端超时转换。

明确故障组合是 Npgsql 10.0.1、.NET 10 与 PostgreSQL 14.19。同一复制流程在 9.0.4 中可以等待消息。10.0.1 的读缓冲设置会把非正超时转换为 TimeSpan.Zero;这与调用者希望“无限等待”的语义不一致。不要仅凭这条异常认定复制槽损坏,或认定服务器把无限参数拒绝了。

保留槽与进度,先验证驱动修正

记录实际包版本、复制槽名、发布名、最后已处理和已确认的 LSN。不要删除复制槽重新开始:这会影响积压 WAL 与恢复位置,可能造成遗漏或重复消费。

Npgsql 10.0.3 的正式源码已在对应读缓冲路径中,把非正读超时转换为 Timeout.InfiniteTimeSpan。在依赖允许的分支升级,保留原槽、发布和消费逻辑,用同样的无限超时设置复查。先核对部署进程实际加载版本,不只看项目文件。

若暂时无法升级,可在隔离环境验证改用业务允许的有限超时,并完整处理超时后的重连与进度恢复。不要直接把业务等待时间任意拉长,再把连接不退出当成修复。TimeSpan.Zero 在不同版本和不同超时属性中的语义也可能不同,不能把它作为跨版本通用的“无限”写法。

无限等待仍需要取消和反馈

修正读超时不意味着复制流永远不需要退出。调用方仍应传入自己的 CancellationToken,并按现有逻辑发送复制状态,维护已接收、已落盘或已应用位置。具体确认点取决于业务的持久化边界,不能仅因读到一条消息就提前确认尚未可靠处理的数据。

验收应覆盖三个阶段:空闲时能等待而非立即超时;新事务产生后能收到预期消息;主动取消能让任务有序结束并关闭连接。随后从保存的进度恢复,检查没有丢失已承诺处理的数据,并按应用既有幂等策略处理可能重放。

保留升级前依赖锁和超时配置。回退驱动时连同配置一起评估,但不要回退已提交的业务处理进度。这个问题的处理对象是客户端复制读超时,不需要改表、重建发布或清理服务器 WAL 文件。