设为首页 收藏本站
查看: 1272|回复: 0

[经验分享] 浅谈 Mongo DB 的 oplog

[复制链接]

尚未签到

发表于 2016-12-2 08:31:43 | 显示全部楼层 |阅读模式
当我们使用 Mysql 数据库的时候,可以开启 binlog,除了做主从同步以外,我们还可以通过观察检索binlog日志知道某个表在指定时间内的操作历史。
那么在 Mongo DB 中是否也存在这样的东东呢?答案是肯定的,这个东西就是 oplog。
当Mongo DB 被设置成主库时(这一点很重要),在 local db 下有个 collection 叫oplog.$main ,这个就是Mongo 的 oplog。
例如,我们在 test 库上创建一个 collection 叫 employee,插入一个叫“小王”的员工,然后将这个小王变性为“女”,删除掉这个叫小王的员工。这就是一个典型的CRUD操作了。

> use test
switched to db test
> db.employee.insert({name:"小王", sex:"男"})
> db.employee.update({name:"小王"}, {$set : {sex:"女"}})
> db.employee.find();
{ "_id" : ObjectId("521272c7dd01ef8a1598a522"), "name" : "小王", "sex" : "女" }
> db.employee.remove({name:"小王"})
> db.employee.find();
>

我们查查对 employee 进行操作的所有的 oplog 记录

> use local
switched to db local
> db.oplog.$main.find({ns : "test.employee"});
{ "ts" : { "t" : 1376940743000, "i" : 1 }, "op" : "i", "ns" : "test.employee", "o" : { "_id" : ObjectId("521272c7dd01ef8a1598a522"), "name" : "小王", "sex" : "男" } }
{ "ts" : { "t" : 1376940770000, "i" : 1 }, "op" : "u", "ns" : "test.employee", "o2" : { "_id" : ObjectId("521272c7dd01ef8a1598a522") }, "o" : { "$set" : { "sex" : "女" } } }
{ "ts" : { "t" : 1376940828000, "i" : 1 }, "op" : "d", "ns" : "test.employee", "b" : true, "o" : { "_id" : ObjectId("521272c7dd01ef8a1598a522") } }
>

可以看到一共有3条,对应了新增、修改、和删除操作,字段含义如下:

  • ts:操作发生时的时间戳,这个时间戳包含两部分内容t和i,t是标准的时间戳(自1970年1月1日 00:00:00 GMT 以来的毫秒数)而i是一个序号,目的是为了保证 t 与 i 组合出的 Mongo 时间戳 ts 可以唯一的确定一条操作记录
  • op:操作类型,插入对应i;更新对应u;删除对应d;但有一种情况是n,它表示无操作(no-op),紧紧代表一个消息信息。
  • ns:这个操作的库和collection的组合
  • o与o2:他们都是操作相关的数据内容

关于oplog的具体内容可以参考下面两个链接
http://stackoverflow.com/questions/11805057/reading-mongodb-binlogs
http://www.kchodorow.com/blog/2010/10/12/replication-internals/
MongoDB的oplog默认大小是空闲磁盘空间的5%。因为有理论认为如果你在单位时间(假设为x)内写了5% 的磁盘空间,那么你将在 19x 的时间内将磁盘耗尽。关于如何调整oplog的大小可以参考下面链接
http://www.kchodorow.com/blog/2011/02/22/resizing-your-oplog/
我之前做了一个对oplog进行查询的小工具。
使用时需要先配置要查询的条件(oplog.properties 文件),例如

# 欲查询的 Mongo DB 的主机、端口和库
mongo.host=172.0.0.1
mongo.port=40017
mongo.db=test
# 查询条件
#   query.collection - 要查询的 Mongo DB collection.
#   query.field       - 要查询的字段名称.
#   query.type        - 要查询的字段类型,支持内容为: "Integer", "String", "Boolean", "Long"
#   query.value       - 要查询的字段值.
#   query.if_value_null - 这个值如果为 "true" 表示要查询的字段值为null.
query.collection=employee
query.field=_id
query.type=String
query.value=521272c7dd01ef8a1598a522
query.if_value_null=false
# 输出相关参数
#  output.directory    - 希望输出文件的路径.
#  output.filename   - 希望输出的文件名,但事实上你得到两个文件:
#            filename.json (json format)
#            filename.html (html format)
output.directory=/tmp/
output.filename=output


在之前的例子中你已经发现了,更新时的查询条件是不会记录在oplog中的,但所有相关操作都会记录 _id 值。所以我这里直接查找_id值为521272c7dd01ef8a1598a522 的内容,那么假如记录被删除如何找到 _id 值呢?我想这就需要我们在设计业务逻辑时做一下妥协,如果要物理删除一条记录,最好在另一个库或日志文件中将这个记录原来的 _id 值记录一下。
执行后会生成两个文件,一个是json格式保存的oplog原始内容(方便二次处理),另一个是html格式方便阅读的内容,看起来如下图所示:
DSC0000.png

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-308412-1-1.html 上篇帖子: mongo数据的导出 下篇帖子: Mongo shell 函数详解
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表