6.Mongodb之Oplog日志

  Mongodb的主从复制是基于Oplog日志进行的,有点类似于Mysql的binlog日志,当对primary进行DML或者DDL之后,这些操作都会将记录到Oplog日志中,然后这些操作会重新在Secondary节点上执行一遍。MongoDB通过这种Oplog操作日志同步模式,最终保证Secondary和Primary节点中的数据一致性。

1.Oplog集合包含的内容分析

  Oplog操作日志是实现复制集节点之间数据异步/同步的关键,Mongodb利用一个为local.oplog.rs的集合保存这些Oplog日志,承载数据的每个复制集节点都会有一个这样的集合。

复制代码
rs0:SECONDARY> db.oplog.rs.findOne()
{
    "op" : "n",
    "ns" : "",
    "o" : {
        "msg" : "initiating set"
    },
    "ts" : Timestamp(1650291242, 1),
    "v" : NumberLong(2),
    "wall" : ISODate("2022-04-18T14:14:02.502Z")
}
复制代码

其中:ts是操作时间,h是全局唯一标识,v是Oplog的版本,op是操作类型,ns是操作的对象,o是操作的内容

2.Oplog的默认大小以及性能影响

  复制集节点在启动时均会创建一个保存操作日志的集合local.oplog.rs,由于此集合是一个固定大小类型的集合,因此系统会默认为其分配一定大小的存储空间。

  对于运行在windows或unix中的WiredTiger存储引擎,默认的Oplog大小等于“空闲的磁盘空间的5%左右”,最小不能低于990MB,最大不能超过50GB.

  这里看一下oplog的默认配置信息:命令:rs.printRelicationInfo()  

rs0:SECONDARY> rs.printReplicationInfo()
configured oplog size:   990MB
log length start to end: 859965secs (238.88hrs)
oplog first event time:  Mon Apr 18 2022 22:14:02 GMT+0800 (CST)
oplog last event time:   Thu Apr 28 2022 21:06:47 GMT+0800 (CST)
now:                     Sun May 01 2022 12:28:55 GMT+0800 (CST)

  log length start to end:表示Oplog能够承载多长时间范围内的操作日志,另外在大多数情况下,采用系统默认分配的Oplog大小即可,Oplog能过容纳所有写操作日志并确保及时复制到其他节点上(不会出现来不及复制的日志条目被后面写操作产生的日志覆盖的情况)

3.Oplog集合大小的修改

  当数据库处于高负载的插入、删除、修改等写操作场景下时,Oplog日志条目会快速增加,如果A节点中日志数量少于primary节点中日志数据的数量,可能出现Primary节点上的操作日志还未被复制过去,就被新写入的操作日志覆盖,最终导致A节点中的数据与Primary节点中的数据不一致。

  当出现这种情况时,可以适当修改一下oplog的大小,使得固定大小的oplog集合能够一次性容纳更多写操作日志,以便A节点有足够的时间来完成操作日志同步。

  先完成Secondary节点中的Oplog集合大小修改,再完成Primary节点上的修改  

rs0:SECONDARY> db.oplog.rs.stats().maxSize         //查看oplog大小
1038090240

  然后再切到admin数据库下,执行replSetResizeOplog命令完成修改:

复制代码
rs0:SECONDARY> use admin    ##这里需要切换到admin数据库下才能进行修改
switched to db admin
rs0:SECONDARY> db.adminCommand({replSetResizeOplog:1,size:1000}) ##这里单位是MB
{
    "ok" : 1,
    "$clusterTime" : {
        "clusterTime" : Timestamp(1651151207, 1),
        "signature" : {
            "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
            "keyId" : NumberLong(0)
        }
    },
    "operationTime" : Timestamp(1651151207, 1)
}
rs0:SECONDARY> use local
switched to db local
rs0:SECONDARY> db.oplog.rs.stats().maxSize
1048576000
复制代码

    注意上面的修改只会修改当前Secondary节点中的Oplog集合大小,其他节点和Primary节点中的Oplog集合大小不变。

    重复以上步骤,完成对其他节点和Primary节点中Oplog集合大小得到修改。

4.oplog的运行模式?

  Oplog大小的配置大小oplogSizeMB参数定义其大小,该参数在集群初始化之前有效,一旦集群初始化完毕,再次修改,将不会生效。

  然后Oplog是轮滚写入的,这和binlog是有点不同,Mysql的binlog是追加写入的,满足一定大小之后,切换到下一个文件中,Oplog更像一个轮子,如下:

  

  如果旧的文档记录还没有同步到副本集,新的文档就写入覆盖了旧的文档,那么同步的过程将会失败。oplog也不能设置过大,过大的oplog会占用大量磁盘空间,而且在从节点应用oplog的时候时间也会过长。所以,一个合适的oplog的设置是很关键的。

5.Oplog的同步机制

  如果新增的副本节点,或者其它的副本延迟太久,这种情况下,源主节点已经领先当前节点太多,Mongodb则会对当前节点进行初始化,初始化的时候,当前节点会从另外一个副本成员进行完整的数据复制,包含整个数据文件以及Oplog的复制。

  如果节点只是短暂的宕机,后来又恢复了,重新同步的时候它会对比自身和其它节点的状态,从而选择数据比自己新的节点进行同步。当然我们也可以手工指定同步对象,不过采用自动同步的方法比较好,因为Mongodb本身的特点就是故障自愈。

  

 

posted on   太白金星有点烦  阅读(302)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· DeepSeek “源神”启动!「GitHub 热点速览」
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 我与微信审核的“相爱相杀”看个人小程序副业
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
· DeepSeek R1 简明指南:架构、训练、本地部署及硬件要求

导航

< 2025年2月 >
26 27 28 29 30 31 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 1
2 3 4 5 6 7 8
点击右上角即可分享
微信分享提示