MongoDB 重演 oplog 报错: cannot apply insert or update operation on a non-existent namespace 错误解决方法
1 问题现象
在进行mongodb oplog 增量恢复操作时,命令报错, 相关的背景知识这里不再描述,参考之前的博客:
MongoDB 备份与恢复 说明
https://www.cndba.cn/dave/article/107972Mongodump Failed: error parsing query as Extended JSON 错误解决方法
https://www.cndba.cn/dave/article/108036
删除备份目录下的local 文件之后,在进行恢复,否则会报如下错误:
MongoDB 4.4 mongorestore can’t drop live oplog while replicating 错误解决方法
https://www.cndba.cn/dave/article/108037
这里看错误信息:
[dave@www.cndba.cn oplog_backup]# mongorestore --username=root --password=root --host=127.0.0.1 --port=27017 --authenticationDatabase admin --oplogReplay --oplogFile /data/mongodb/oplog_backup/local/oplog.rs.bson --dir empty
2022-06-01T14:43:41.439+0800 preparing collections to restore from
2022-06-01T14:43:41.439+0800 replaying oplog
2022-06-01T14:43:41.451+0800 Failed: restore error: error applying oplog: applyOps: (NamespaceNotFound) cannot apply insert or update operation on a non-existent namespace admin.sbtest4: { ts: Timestamp(1652420085, 5631), t: 8, h: null, v: 2, op: "i", ns: "admin.sbtest4", o: { _id: 753131, k: 130945, c: "62292415410-95388203585-67679110649-47028447385-45875177663-93632996761-25009143007-28772670425-57302463101-04350746972", pad: "60666224225-78605000196-77407425475-55130133837-32853691289" } }
2022-06-01T14:43:41.451+0800 0 document(s) restored successfully. 0 document(s) failed to restore.
[dave@www.cndba.cn oplog_backup]#
这里直接报错如下:
Failed: restore error: error applying oplog: applyOps: (NamespaceNotFound) cannot apply insert or update operation on a non-existent namespace admin.sbtest4:
2 分析过程
这里admin.sbtest4的表示我们之前的操作drop 的表,并且是我们全备之前的操作。 只不过这个记录还保存在oplog 中,因为我们在导增量的oplog 是按小于某个时间来导出的。 所以导致全备之前的数据还在oplog中。
而全备恢复之后,这个对象并不存在,所以在应用oplog时报NamespaceNotFound。
导致出现这个问题的大致逻辑如下:
- 时间T1:创建表 cndba
- 时间T2:oplog 导出的开始时间
- 时间T3:drop 表cndba
- 时间T4:全备mongodb
- 时间T5:新建测试表dave
- 时间T6:oplog 导出的终止时间
在这个流程下,我们利用oplog 进行增量恢复的时间点是T4 + T6。 此时oplog 里并没有T1 时间cndba 表的创建记录。 所以T3对cndba 表的操作就会失败,就会报集合不存在的错误:
(NamespaceNotFound) cannot apply insert or update operation on a non-existent namespace
当然这里只是一个逻辑推理。
BTW: 此段分析感谢马程程老师的指导。
3 解决方法
解决这个问题的方法,也很简单,就是在导出oplog 时,将开始时间调整到全备开始时间之前,但不要超过太前,避免出现其他的DDL 操作对后面oplog 应用的影响。
这里提前一点并没有影响,因为oplog中的每个操作都是幂等的。 也就是说,在目标库中应用oplog时,无论应用一次还是多次都是相同的结果。
查看当前备份时间:
[dave@www.cndba.cn ~]# cd /data/mongodb/backup
[dave@www.cndba.cn backup]# ll
total 4
drwxr-xr-x 2 root root 128 Jun 1 13:54 admin
drwxr-xr-x 2 root root 92 Jun 1 13:54 cndba
drwxr-xr-x 2 root root 251 Jun 1 13:54 config
drwxr-xr-x 2 root root 110 Jun 1 13:54 m201
-rw-r--r-- 1 root root 206 Jun 1 13:54 oplog.bson
[dave@www.cndba.cn backup]#
我们将开始的时间设置为2022-06-01 13:50:00,转换timestamp为:1654062600
rs0:PRIMARY> var tm = Math.round(new Date("2022-06-01 13:50:00") / 1000)
rs0:PRIMARY> tm
1654062600
rs0:PRIMARY> print(tm)
1654062600
rs0:PRIMARY>
重新导出oplog,这次指定开始时间和截止时间:
[dave@www.cndba.cn oplog_backup]# mongodump --username=root --password=root --host=127.0.0.1 --port=27017 --authenticationDatabase admin -d local -c "oplog.rs" -q '{"ts":{"$gt":{"$timestamp":{"t":1654062600, "i":1}},"$lt": {"$timestamp":{"t":1654063757, "i":1}}}}' --out /data/mongodb/oplog_backup
2022-06-01T20:54:36.134+0800 writing local.oplog.rs to /data/mongodb/oplog_backup/local/oplog.rs.bson
2022-06-01T20:54:36.339+0800 done dumping local.oplog.rs (50675 documents)
[dave@www.cndba.cn oplog_backup]#
全备我们之前已经恢复过了,我们这里直接重演oplog:
[dave@www.cndba.cn oplog_backup]# mongorestore --username=root --password=root --host=127.0.0.1 --port=27017 --authenticationDatabase admin --oplogReplay --oplogFile /data/mongodb/oplog_backup/local/oplog.rs.bson --dir empty
2022-06-01T20:56:01.139+0800 preparing collections to restore from
2022-06-01T20:56:01.140+0800 replaying oplog
2022-06-01T20:56:01.140+0800 skipping applying the config.system.sessions namespace in applyOps
2022-06-01T20:56:01.140+0800 skipping applying the config.system.sessions namespace in applyOps
2022-06-01T20:56:01.141+0800 skipping applying the config.system.sessions namespace in applyOps
2022-06-01T20:56:04.148+0800 oplog 1.44MB
2022-06-01T20:56:07.139+0800 oplog 2.76MB
2022-06-01T20:56:10.139+0800 oplog 4.19MB
2022-06-01T20:56:13.139+0800 oplog 5.75MB
2022-06-01T20:56:16.149+0800 oplog 7.22MB
2022-06-01T20:56:19.149+0800 oplog 8.74MB
2022-06-01T20:56:22.148+0800 oplog 9.90MB
2022-06-01T20:56:25.139+0800 oplog 11.5MB
2022-06-01T20:56:28.150+0800 oplog 13.0MB
2022-06-01T20:56:31.139+0800 oplog 14.4MB
2022-06-01T20:56:34.139+0800 oplog 15.8MB
2022-06-01T20:56:37.139+0800 oplog 17.2MB
2022-06-01T20:56:40.139+0800 oplog 18.6MB
2022-06-01T20:56:43.141+0800 oplog 19.9MB
2022-06-01T20:56:46.139+0800 oplog 21.3MB
2022-06-01T20:56:49.139+0800 oplog 22.7MB
2022-06-01T20:56:51.938+0800 applied 50567 oplog entries
2022-06-01T20:56:51.938+0800 oplog 23.9MB
2022-06-01T20:56:51.938+0800 no indexes to restore for collection m201.ustc
2022-06-01T20:56:51.938+0800 0 document(s) restored successfully. 0 document(s) failed to restore.
[dave@www.cndba.cn oplog_backup]#
应用成功。
版权声明:本文为博主原创文章,未经博主允许不得转载。