mongodb
protocol_error
ai_generated
partial
MongoServerError: 命名空间 'mydb.mycoll' 的恢复令牌无效或已被修剪:resumeAfter 时间戳太旧
MongoServerError: The resume token for namespace 'mydb.mycoll' is invalid or has been pruned: resumeAfter timestamp too old
ID: mongodb/change-stream-resume-token-invalid-for-namespace
70%修复率
87%置信度
1证据数
2023-11-05首次发现
版本兼容性
| 版本 | 状态 | 引入 | 弃用 | 备注 |
|---|---|---|---|---|
| MongoDB 5.0 | active | — | — | — |
| MongoDB 6.0 | active | — | — | — |
| MongoDB 7.0 | active | — | — | — |
| Atlas M10+ | active | — | — | — |
根因分析
变更流的恢复令牌引用了已被修剪的操作日志条目,原因可能是操作日志大小限制,或变更流空闲时间超过操作日志窗口(Atlas 上通常为 24 小时)。
English
A change stream's resume token refers to an oplog entry that has been pruned due to the oplog size limit or because the change stream was idle longer than the oplog window (typically 24 hours on Atlas).
官方文档
https://www.mongodb.com/docs/manual/changeStreams/#resume-a-change-stream解决方案
-
从当前时间开始新的变更流,接受丢失事件的数据损失。在代码中:`collection.watch([], { resumeAfter: null, startAfter: null })` 或使用带有最近时间戳的 `startAtOperationTime`。 -
如果使用 Atlas,通过升级集群层级或启用长期操作日志保留(如果可用)来增加操作日志窗口。对于自管理,增加操作日志大小:`db.adminCommand({ replSetResizeOplog: 1, size: 102400 })`(以 MB 为单位)。 -
实现回退机制:将最后处理的文档 ID 存储在外部存储(例如 Redis)中,并使用 `startAfter` 与最后已知的 _id 来追赶,然后切换回恢复令牌。
无效尝试
常见但无效的做法:
-
90% 失败
The resume token is already invalid; a new change stream must be started from the current time, losing all events between the old token and now.
-
100% 失败
The oplog entry is permanently pruned; retrying will always fail.
-
95% 失败
The error is server-side; no driver can recover a pruned oplog entry.