返回顶部
首页 > 资讯 > 数据库 >mongodb 学习之oplog
  • 305
分享到

mongodb 学习之oplog

2024-04-02 19:04:59 305人浏览 安东尼
摘要

背景:   原来一个同事问我主从mongoDB数据库为什么数据差距很大,我让他察看一下两边有啥不一样,发现主的local库有13G从却很小,进入local之后du发现有一个collect


背景:

   原来一个同事问我主从mongoDB数据库为什么数据差距很大,我让他察看一下两边有啥不一样,发现

主的local库有13G从却很小,进入local之后du发现有一个collection前缀的文件有13g,说明是local数据库中一个集合太大了,推测是oplog太大了,oplog是类似于Mysql的binlog oracle的arcHivelog

当Primary进行写操作的时候,会将这些写操作记录写入Primary的Oplog 中,而后Secondary会将Oplog 复制到本机并应用这些操作,从而实现Replication的功能。
同时由于其记录了Primary上的写操作,故还能将其用作数据恢复。
可以简单的将其视作mysql中的binlog。

为了进一步确认,进入monGodb之后通过

show dbs 

use local

show collections

看到现有的集合

然后

db.getReplicationInfo()

rs.printReplicationInfo()

了解一下复制信息以及oplog大小与使用情况

为进一步确认相应的文件是否为oplog

db.printCollectionStats()

根据展示出来的结果只需要知道两条信息:


"ns" : "local.oplog.$main",

"uri" : "statistics:table:local/collection-2-1716662444632575459"

就可以确认oplog集合的相应文件,oplog如果太大可以清理和修改大小。



MongoDB oplog是一个capped collection,创建capped collection时,createCollection可以设置size(最大字节数)和max(最大文档数)的参数,当这个集合的『总大小超过size』或者『总文档数超过max』时,在新插入文档时就会自动删除一些集合内最先插入的文档,相当于一片环形的存储空间。

oplog(local.oplog.rs集合)默认情况下配置为可用磁盘空间的5%,当oplog写满时,就会开始删除最先写入的oplog,一次正常的insert操作包含如下步骤:

  1. 将文档写入指定的集合

  2. 将写入操作记录到oplog

  3. 如果oplog满了,删除最先写入的oplog

优化策略

MongoDB 3.2为了提升写入性能,使用wiredtiger引擎时,针对local.oplog.rs这个集合的删除策略进行了优化,主要改进:

  1. 将删除动作从用户的写入路径移除,放到后台线程执行

  2. 批量删除,并不是oplog一满就立马触发删除,而是一次删除一批

实施方案

monogd启动时,会根据oplog的最大字节数将整个集合分为10-100个Stone(可以理解为oplog的一段数据,包含多个文档,Stone的具体个数oplogSizeMB的配置相关)。

WiredTigerRecordStore::OplogStones::OplogStones(OperationContext* txn, WiredTigerRecordStore* rs)
    : _rs(rs) {
    //...
    unsigned long long maxSize = rs->cappedMaxSize();

    const unsigned long long kMinStonesToKeep = 10ULL;
    const unsigned long long kMaxStonesToKeep = 100ULL;

    unsigned long long numStones = maxSize / BSONObjMaxInternalSize;
    _numStonesToKeep = std::min(kMaxStonesToKeep, std::max(kMinStonesToKeep, numStones));
    _minBytesPerStone = maxSize / _numStonesToKeep;
    // ...
}

其中_numStonesToKeep为oplog应该保持的Stone个数,而_minBytesPerStone代表每个Stone的最小字节数。

mongodb 学习之oplog

接下来,会根据oplog当前的大小以及_minBytesPerStone来估算下,当前的oplog大致包含的Stone数量,并通过采样的方式来获取每个Stone的起始位置(不能保证每个Stone的大小跟预期完全一样),然后将所有的Stone按顺序存储到一个队列中。

mongod在服务写请求的过程中,每次都会记录下新产生oplog的大小,当新产生的oplog的总量超过_minBytesPerStones时,就会产生一个新的Stone加入到队列中。

void WiredTigerRecordStore::OplogStones::createNewStoneIfNeeded(RecordId lastRecord) {

    if (_currentBytes.load() < _minBytesPerStone) {
        // Must have raced to create a new stone, someone else already triggered it.
        return;
    }

    // ...

    OplogStones::Stone stone = {_currentRecords.swap(0), _currentBytes.swap(0), lastRecord};
    _stones.push_back(stone);

    _pokeReclaimThreadIfNeeded(); // 唤醒后台回收oplog空间的线程
}

当队列中的Stone数量超过_numStonesToKeep,后台线程就会删除最老的Stone里的数据,来回收oplog的存储空间。


修改mongodb oplog size

oplog简介:

oplog:operations log的简写,存储在一个特殊的数据库中(local),oplog就存储在其中的oplog.$main集合里面,这个集合是一个固定集合,新操作会自动替换旧的操作,以保证oplog不会超过预设的大小,其中的每个文档都代表主节点上执行的一个操作,oplog会包含所有对数据有修改的的操作(查询操作不会记录),默认下,oplog大小会占用64位的实例5%的可用磁盘空间。
mongo复制的过程:主节点应用业务操作修改到数据库中,然后记录这些操作到oplog中,从节点复制这些oplog,然后应用这些修改。ps:这些操作是异步的。如果从节点的操作已经被主节点落下很远,oplog日志在从节点还没执行完,oplog可能已经轮滚一圈了,从节点跟不上同步,复制就会停下,从节点需要重新做完整的同步,为了避免此种情况,尽量保证主节点的oplog足够大,能够存放相当长时间的操作记录。

查询oplog的大小及保存的操作记录持续的时长

repltest:PRIMARY> db.printReplicationInfo()
configured oplog size:   1024MB
log length start to end: 3705secs (1.03hrs)
oplog first event time:  Thu Oct 10 2013 11:13:29 GMT+0800 (CST)
oplog last event time:   Thu Oct 10 2013 12:15:14 GMT+0800 (CST)
now:                     Fri Oct 11 2013 16:33:42 GMT+0800 (CST)

查询从节点的数据源列表,其中有数据滞后的时间

repltest:PRIMARY> db.printSlaveReplicationInfo()
source:   192.168.1.101:37017
syncedTo: Fri Oct 11 2013 16:38:16 GMT+0800 (CST)
= 1 secs ago (0hrs)
source:   192.168.1.100:37017
no replication info, yet.  State: ARBITER
so,修改oplog的大小:(下面介绍两种方式)

方式一:

The oplog exists internally as a capped collection, so you cannot modify its size in the course of nORMal operations.另:改变oplog大小,需要在每个节点上执行维护模式。(官方推荐)
步骤:

1:重启一个实例以单机模式,

通常再关闭server之前,使用rs.stepDown() 强制primary成为secondary

2:重新创建一个新大小,

其中包含旧的oplgo的入口条目的oplog

3:重启mongod作为replica set的成员

操作步骤:
1>: Restart a Secondary in Standalone Mode on a Different Port
关闭mongod实例:
repset:PRIMARY> use admin
repset:PRIMARY> db.shutdownServer()
重启mongod实例以单机模式,修改端口,并不要加--replSet参数
#vim /etc/mongo.conf
  dbpath=/var/lib/mongodb
  logpath=/var/log/mongodb/mongo.log
  pidfilepath=/var/run/mongo.pid
  directoryperdb=true
  logappend=true
  #replSet=repset
  bind_ip=192.168.1.100,127.0.0.1
  port=37017
  oplogSize=2000
  fork=true# mongod -f /etc/mongo.conf
备份oplog# mongodump --db local --collection 'oplog.rs' --port 37017
2>: Recreate the Oplog with a New Size and a Seed Entry
保存oplog的最新的时间点
> use local
> db.temp.save( db.oplog.rs.find( { }, { ts: 1, h: 1 } ).sort( {$natural : -1} ).limit(1).next() )
> db.temp.find()
删除旧的oplog
> db.oplog.rs.drop()
3> :Create a New Oplog
创建一个新的Oplog,大小为2G
> db.runCommand( { create: "oplog.rs", capped: true, size: (2 * 1024 * 1024 * 1024) } )
插入前面保存的旧的oplog的时间点的记录
> db.oplog.rs.save( db.temp.findOne() )
> db.oplog.rs.find()
4>:Restart the Member:
关闭单机实例:
> use admin
> db.shutdownServer()
修改回配置# vim /etc/mongo.conf
  dbpath=/var/lib/mongodb
  logpath=/var/log/mongodb/mongo.log
  pidfilepath=/var/run/mongo.pid
  directoryperdb=true
  logappend=true
  replSet=repset
  bind_ip=192.168.1.100,127.0.0.1
  port=37017
  oplogSize=2000
  fork=true
启动mongod
# mongod -f /etc/mongo.conf
重复上述步骤到所有需要更改的节点。

方式二:

步骤:
1:停掉所有replca set节点.
2:主节点删除local库下的文件,从节点删除数据目录下所有文件.
3:修改所有节点配置文件.
4:重启所有节点.
5:重新配置replca set,从节点会重新同步所有数据(initial sync).
ps:此法好处是简单,但需要停掉服务,且如果数据量很大,初始同步的成本较高

1>:关闭mongod实例(所有节点)

> use admin
> db.shutdownServer()

2>:删除local数据库下的所有文件(PRIMARY节点)

# rm -rf /var/lib/mongodb/local/*
  删除mongo数据目录(其他节点上操作,可不要删错哦,建议所有rm操作先mv,待无问题时候再删除)# rm -rf /var/lib/mongodb/*

3> 修改所有节点配置文件(oplogsize)

# vim /etc/mongo.conf
  dbpath=/var/lib/mongodb
  logpath=/var/log/mongodb/mongo.log
  pidfilepath=/var/run/mongo.pid
  directoryperdb=true
  logappend=true
  replSet=repset
  bind_ip=192.168.1.100,127.0.0.1
  port=37017
  oplogSize=2000
  fork=true

4> 重启所有节点mongod

> mongod -f /etc/mongo.conf



您可能感兴趣的文档:

--结束END--

本文标题: mongodb 学习之oplog

本文链接: https://lsjlt.com/news/44247.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • mongodb 学习之oplog
    背景:   原来一个同事问我主从mongodb数据库为什么数据差距很大,我让他察看一下两边有啥不一样,发现主的local库有13G从却很小,进入local之后du发现有一个collect...
    99+
    2024-04-02
  • Mongodb 之 oplog
    一开始我就以为 oplog 应该就类似于 mysql bin-log 而事实上,确实差不多。oplog 也是用于复制集间由 Primary 记录,Secondary 用来同步。从而保持数据一致。 最近遇到了误删db(删库不能跑路)...
    99+
    2015-03-13
    Mongodb oplog
  • MongoDB更改oplog大小
    【问题说明】        在生产环境新增secondary:10.9.197.6:27017...
    99+
    2024-04-02
  • NodeJS学习笔记之MongoDB模块
    一,开篇分析 这篇属于扩展知识篇,因为在下面的文章中会用到数据库操作,所以今天就来说说它(Mongodb模块)。 (1),简介 MongoDB是一个基于分布式文件存储的数据库。由C++语言编写。旨在为WE...
    99+
    2022-06-04
    学习笔记 模块 NodeJS
  • MongoDB 更改 Oplog Size 大小
    MongoDB 的副本集同步中 Oplog 占了非常关键的作用。Oplog Size 可不可以随意更改?https://docs.mongodb.com/manual/reference/configura...
    99+
    2024-04-02
  • MongoDB中怎么开启Oplog
    这篇文章给大家介绍MongoDB中怎么开启Oplog,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。配置过程其实配置的过程比较简单。step 1 : 在配置文件中 添加副本集参数(rep...
    99+
    2024-04-02
  • MongoDB学习整理之访问控制
    MongoDB学习整理之访问控制  1、限制特定IP地址访问,只需启动时加入--bind_ip 参数 ,客户端连接时也需要添加--host     &nbs...
    99+
    2024-04-02
  • 学习MongoDB(一)
    一 . MongoDB 1.概述 CMS采用MongoDB数据库存储CMS页面信息,CMS选用Mongodb的原因如下: 1、Mongodb是非关系型数据库,存储Json格式数据 ,数据格式灵活。 2、相比课程管理等核心数据CMS数...
    99+
    2014-10-12
    学习MongoDB(一)
  • MongoDB Oplog中的字段介绍
    {     "ts" : Timestamp(1446011584, 2),         "h" : NumberLong("16873591...
    99+
    2024-04-02
  • Mongodb学习总结
    Mongodb相关操作总结 2020/4/2 Mongodb使用的是类似与json字符串的形式存储数据 [ { key:value }, { key:value }, ] Mongodb使用了不存在的对...
    99+
    2019-08-19
    Mongodb学习总结
  • MongoDB学习系列
    用mongodb已经有3年多时间,但是一直没有系统的学习过,更多时候是在问题中摸索,随着最近遇到的问题越来越多,回过头系统的了解下这个数据库,就显得格外有必要了。本稿将从如下几个方面介绍,当然文中内参阅了很...
    99+
    2024-04-02
  • MongoDB学习(三) --- MongoDB Java入门
    1、搭建测试环境 步骤一:创建 maven 项目 父项目的pom文件 4.0.0 com.tqylxuecheng xc_parent pom 1.0-SNAPSHOT ...
    99+
    2022-03-31
    MongoDB学习(三) --- MongoDB Java入门
  • mongo db 学习笔记 之一: mongodb 初认识
    官网文章,对比SQL和mongodbhttp://docs.mongodb.org/manual/reference/sql-comparison/db --显示当前使用的库show dbs --显示所有库...
    99+
    2024-04-02
  • mongoDB复制集修改 oplog 大小
    ctiy:PRIMARY> use local switched to db local ctiy:PRIMARY> db.oplog.rs.stats().maxSize //查看大小 NumberLong("53687091200...
    99+
    2019-07-06
    mongoDB复制集修改 oplog 大小 数据库入门 数据库基础教程 数据库 mysql
  • Mongodb中oplog的原理是什么
    Mongodb中oplog的原理是什么,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。Oplog 是 MongoDB 实现复制集的关键数据结...
    99+
    2024-04-02
  • MongoDB中 oplog的作用是什么
    本篇文章为大家展示了MongoDB中 oplog的作用是什么,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。 1:oplog简介 oplog是local库下的一个...
    99+
    2024-04-02
  • MongoDB学习(四) --- MongoDB 整合Spring Data
    1、环境搭建 步骤一:修改pom文件,更新依赖 org.springframework.boot spring-boot-starter-data-mongodb org.projectlombok lombok ...
    99+
    2021-09-17
    MongoDB学习(四) --- MongoDB 整合Spring Data
  • MongoDB学习7:Change Strean
    1.什么是Change Stream? Change Stream是MongoDB用于实现变更追踪的解决方案,类似于关系型数据库的触发器,但原理不完全相同 Change Stream 触发器 触发方式 异步 同步(事务保证)...
    99+
    2015-04-25
    MongoDB学习7:Change Strean 数据库入门 数据库基础教程 数据库 mysql
  • mongodb的学习过程
        近段时间感觉有点迷茫了,不知道该做什么,今天上班看看自己的监控数据,想想能不能为了读写速度我把数据写入到mongodb里面这种非关系型数据库里面呢,下面开始学习mong...
    99+
    2024-04-02
  • mongodb中oplog介绍和格式详析
    目录1. 基本概念 2. Oplog 的默认储存大小 3. 可能需要更大oplog的工作负载 4. Oplog状态 5. Oplog格式 6. CUD操作和Oplog的对应关系 de...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作