Debezium对接MongoDB时无法获取更新/删除事件的before值
Hey there, let's troubleshoot why you're seeing null for the before value in update and delete events when using Debezium with MongoDB and Pub/Sub. Here's what you need to check and adjust:
1. 确认MongoDB部署类型
Debezium的MongoDB连接器依赖MongoDB的复制机制(复制集的oplog或分片集群的分片日志)来捕获变更历史。如果你运行的是单节点MongoDB实例,它不会生成跟踪变更前后状态所需的oplog数据,这就是before值为null的原因之一。请确保你的MongoDB部署为复制集或分片集群。
2. 调整配置修复更新事件的before值
默认情况下,MongoDB的Change Stream不会返回更新操作的完整预更新文档。要让更新事件的before值正常填充,在你的Debezium源配置中添加以下参数:
debezium.source.mongodb.change.stream.full.document=updateLookup
这个参数会让MongoDB在Change Stream中包含更新前的完整文档,Debezium随后会将其映射到事件的before字段中。
3. 处理删除事件(MongoDB的固有限制)
MongoDB的Change Stream在删除事件中不会原生返回完整的被删除文档——它只会提供documentKey(即被删除文档的_id),这就是删除事件中before值为null的原因。要获取删除前的完整文档,你有两个可选方案:
方案A:启用MongoDB的预镜像功能(MongoDB 4.0+)
首先需要在集合级别开启预镜像。针对每个需要跟踪的集合,在MongoDB shell中执行以下命令:
db.runCommand({ collMod: "你的目标集合名称", changeStreamPreAndPostImages: { enabled: true } })
然后在Debezium配置中添加以下参数,让它使用预镜像数据:
debezium.source.mongodb.change.stream.full.document.before=required
配置完成后,Debezium会将删除前的完整文档状态填充到before字段中。
方案B:手动预记录删除操作
如果预镜像方案不可行,你可以修改应用逻辑:在执行删除操作前,将文档副本写入一个专门的“删除审计”集合,之后可以通过消费这个集合来获取完整的被删除文档数据。
4. 验证用户权限
确保你的MongoDB用户(debz)拥有必要的权限:
- 目标数据库(
dbname)的read和readWrite权限 - 访问Change Stream数据的
changeStream权限 - 如果使用预镜像,确保用户拥有修改集合设置和访问预镜像数据的权限
完成以上修改后,重启Debezium连接器并测试更新/删除操作——你应该能看到符合预期的before值(更新事件会立即生效,删除事件在启用预镜像或实现手动日志后生效)。
备注:内容来源于stack exchange,提问作者Sudharsan K

