拦截或过滤掉MongoDB中的oplog事务

时间:2014-10-06 01:50:35

标签: mongodb

有一个MongoDB,它有我想要检查的有趣数据。不幸的是,由于尺寸问题,每48小时一次,数据库被清除“旧”记录。

我创建了一个副本集,其副本数据库系统的优先级为0,表决为0,以免干扰主数据库性能。这很好用,因为我可以查询辅助数据并获取我的数据。但是,有很多情况下我的系统无法及时处理所有记录,如果我在48小时内没有收到这些记录,将丢失一些旧记录。

有没有办法可以将oplog缓存到另一个系统上,然后我可以在闲暇时处理它,可能会删除删除直到我准备好了?

我考虑了slavedelay参数,但这会影响所有事务。我还将Tungsten Replicate视为一种解决方案,因此我可以实际缓存oplog,但是,它们不支持MongoDB作为数据源。

oplog是否以纯文本形式存储在辅助文件上,以便我可以阅读它并从中提取我想要的内容。

任何对此的指示都会有所帮助,遗憾的是我在MongoDB网站上找不到很多关于Oplog的文档。

2 个答案:

答案 0 :(得分:1)

MongoDB oplog存储为本地数据库中名为“oplog.rs”的上限集合:

use local
db.oplog.rs.find()

如果要在oplog中存储更多旧数据供以后使用,可以尝试增加该集合的大小。见http://docs.mongodb.org/manual/tutorial/change-oplog-size/

或者,您可以将oplog.rs重新创建为无上限的集合(尽管不建议这样做,因为您必须手动清理oplog)。按照相同的步骤增加上面的大小,但在重新创建oplog时,请使用此命令

db.runCommand( { create: "oplog.rs", capped: false})

另一种解决方案是使用以下命令将opron创建到文件夹YYYYMMDD:

mongodump --db local --collection oplog.rs -o $(date +%Y%m%d)

希望有所帮助。

答案 1 :(得分:0)

我想知道你为什么要手动这样做。 “规范”的方法是确定记录的生命周期或到期日期。如果它是一辈子的话,你会像

那样
db.collection.insert({'foo':'bar' [...], created: ISODate("2014-10-06T09:00:05Z")})

db.collection.ensureIndex({'created':1},{expireAfterSeconds:172800})

通过这样做,一个名为TTLMonitor的线程将每分钟唤醒并删除所有已创建字段超过两天的文档。

如果每个文档都有一个固定的截止日期,您基本上也会这样做:

db.collection.insert({'foo':'bar' [...], expirationDate: ISODate("2100-01-01T00:00:00Z"})

db.collection.ensureIndex({expirationDate:1},{expireAfterSeconds:0})

这将在expirationDate后的第一轮TTLMonitor中清除文档。

您可以将expireAfterSeconds调整为一个值,该值可以安全地允许您在清除记录之前处理记录,将整体大小保持在可接受的需求,并确保即使您的应用程序在清除工作期间发生故障,记录被删除。 (更不用说你不需要自己维护清除逻辑了。)

有人说,并希望它对你有用,我认为你的问题是一个概念问题。

您有缩放问题。您的系统无法处理峰值,因此它偶尔无法及时处理所有数据。而不是摆弄MongoDB的内部(这可能是非常危险的,正如@chianh正确指出的那样),你应该通过识别你的瓶颈并根据你的峰值进行缩放来相应地进行扩展。