![从 MongoDB 原始文件恢复数据](https://linux22.com/image/640088/%E4%BB%8E%20MongoDB%20%E5%8E%9F%E5%A7%8B%E6%96%87%E4%BB%B6%E6%81%A2%E5%A4%8D%E6%95%B0%E6%8D%AE.png)
我们使用 mongodb 作为数据库并设置了 replset(两台服务器),但我们错误地删除了两台服务器上 /path/to/dbdata 下的一些原始文件。之后,我们用来extundelete
恢复已删除的文件。我们extundelete
在两台服务器上运行并合并结果,如 database.1、database.2 等。我们无法启动 mongod,启动 mongod 或执行 mongodump 时出现以下错误,以下是控制台输出:
root@mongod:/opt/mongodb# mongodump --repair --dbpath /opt/mongodb -d database_production
Thu Aug 21 16:22:43.258 [tools] warning: repair is a work in progress
Thu Aug 21 16:22:43.258 [tools] going to try and recover data from: database_production
Thu Aug 21 16:22:43.262 [tools] Assertion failure isOk() src/mongo/db/pdfile.h 392
0xde1b01 0xda42fd 0x8ae325 0x8ac492 0x8bd8e0 0x8c1c51 0x80e345 0x80e607 0x80e6a4 0x6db92a 0x6dc1ff 0x6e0db9 0xd9e45e 0x6ccdc7 0x7f499d856ead 0x6ccc29
mongodump(_ZN5mongo15printStackTraceERSo+0x21) [0xde1b01]
mongodump(_ZN5mongo12verifyFailedEPKcS1_j+0xfd) [0xda42fd]
mongodump(_ZNK5mongo7Forward4nextERKNS_7DiskLocE+0x1a5) [0x8ae325]
mongodump(_ZN5mongo11BasicCursor7advanceEv+0x82) [0x8ac492]
mongodump(_ZN5mongo8Database19clearTmpCollectionsEv+0x160) [0x8bd8e0]
mongodump(_ZN5mongo14DatabaseHolder11getOrCreateERKSsS2_Rb+0x7b1) [0x8c1c51]
mongodump(_ZN5mongo6Client7Context11_finishInitEv+0x65) [0x80e345]
mongodump(_ZN5mongo6Client7ContextC1ERKSsS3_b+0x87) [0x80e607]
mongodump(_ZN5mongo6Client12WriteContextC1ERKSsS3_+0x54) [0x80e6a4]
mongodump(_ZN4Dump7_repairESs+0x3a) [0x6db92a]
mongodump(_ZN4Dump6repairEv+0x2df) [0x6dc1ff]
mongodump(_ZN4Dump3runEv+0x1b9) [0x6e0db9]
mongodump(_ZN5mongo4Tool4mainEiPPc+0x13de) [0xd9e45e]
mongodump(main+0x37) [0x6ccdc7]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xfd) [0x7f499d856ead]
mongodump(__gxx_personality_v0+0x471) [0x6ccc29]
assertion: 0 assertion src/mongo/db/pdfile.h:392
Thu Aug 21 16:22:43.271 dbexit:
Thu Aug 21 16:22:43.271 [tools] shutdown: going to close listening sockets...
Thu Aug 21 16:22:43.271 [tools] shutdown: going to flush diaglog...
Thu Aug 21 16:22:43.271 [tools] shutdown: going to close sockets...
Thu Aug 21 16:22:43.272 [tools] shutdown: waiting for fs preallocator...
Thu Aug 21 16:22:43.272 [tools] shutdown: closing all files...
Thu Aug 21 16:22:43.273 [tools] closeAllFiles() finished
Thu Aug 21 16:22:43.273 [tools] shutdown: removing fs lock...
Thu Aug 21 16:22:43.273 dbexit: really exiting now
我的环境:
- Debian 3.2.35-2 x86_64(它是一个XEN虚拟机)
- mongodb 2.4.6
我们没有删除.0
和.ns
文件。
我们尝试创建一个具有相同名称的新数据库,并将这些复制到新数据库,但仍然遇到相同的错误db.ns
。db.2
db.3
有什么方法可以检查原始.ns 和数据文件的有效性,以及如何恢复数据库?
答案1
正如 Stennie 正确指出的那样,您的数据几乎肯定会丢失。
原因是 MongoDB 复制不是数据文件的二进制复制。相反,优化后的语句保存在一个名为“oplog”的特殊集合中,辅助节点使用可跟踪游标连接到该集合。当 MongoDB 优化了查询后,它会被写入所述 oplog,连接的辅助节点可以读取结果查询。
因此,根据您初始化复制时副本集的数据文件的状态,同一个文档可能驻留在主服务器上的数据文件 1 中,而它却驻留在一个辅助服务器上的数据文件 42 中,并驻留在另一个辅助服务器上的数据文件 3 中。归根结底,文档在数据文件中的位置是不可预测的*,更不用说保证了。
我不想这么说,但除非进行极其昂贵的数据取证,否则您的数据是无法恢复的。
*尽管它可以描述为“能够保存文档数据和填充的二进制表示的第一个连续的空闲字节范围”。