0

0

MongoDB更改oplog大小

蓮花仙者

蓮花仙者

发布时间:2025-07-18 11:36:35

|

340人浏览过

|

来源于php中文网

原创

【问题说明】

在生产环境中添加了新的副本集成员(secondary):10.9.197.6:27017,数据量为140G。然而,该成员同步了一天后仍未追上主节点的数据。通过以下方式查看同步情况:

查看主从复制状态的命令,以下两种方式的结果是一致的:

方式一:

use admin
db.runCommand( { replSetGetStatus : 1 } )

指定的值不会影响命令的输出。此命令提供的数据源自于包含在由副本集的其他成员发送到当前实例的心跳中的数据。由于心跳的频率,这些数据可能是几秒钟过期。详情请参考官档:https://www.php.cn/link/5fc4698a9539a70b368c5aa9736c49eb

方式二:

rs.status()

查看复制状态,发现状态是"stateStr" : "RECOVERING"。信息为"infoMessage" : "could not find member to sync from",使用 rs.syncFrom("10.9.161.130:27017") 也无法让其继续正常同步。具体信息如下:

kk-comic-shard01:RECOVERING> rs.status() {
 "set" : "kk-comic-shard01",
 "date" : ISODate("2017-02-07T02:12:17.613Z"),
 "myState" : 3,
 "term" : NumberLong(5),
 "heartbeatIntervalMillis" : NumberLong(2000),
 "members" : [
 {
 "_id" : 2,
 "name" : "10.9.95.69:27017",
 "health" : 1,
 "state" : 7,
 "stateStr" : "ARBITER",
 "uptime" : 41966,
 "lastHeartbeat" : ISODate("2017-02-07T02:12:14.490Z"),
 "lastHeartbeatRecv" : ISODate("2017-02-07T02:12:15.696Z"),
 "pingMs" : NumberLong(0),
 "configVersion" : 19
 },
 {
 "_id" : 4,
 "name" : "10.9.161.130:27017",
 "health" : 1,
 "state" : 1,
 "stateStr" : "PRIMARY",
 "uptime" : 41966,
 "optime" : {
 "ts" : Timestamp(1486433534, 636),
 "t" : NumberLong(5)
 },
 "optimeDate" : ISODate("2017-02-07T02:12:14Z"),
 "lastHeartbeat" : ISODate("2017-02-07T02:12:14.489Z"),
 "lastHeartbeatRecv" : ISODate("2017-02-07T02:12:16.435Z"),
 "pingMs" : NumberLong(0),
 "electionTime" : Timestamp(1486103572, 783),
 "electionDate" : ISODate("2017-02-03T06:32:52Z"),
 "configVersion" : 19
 },
 {
 "_id" : 5,
 "name" : "10.9.184.101:27017",
 "health" : 1,
 "state" : 2,
 "stateStr" : "SECONDARY",
 "uptime" : 41966,
 "optime" : {
 "ts" : Timestamp(1486433534, 629),
 "t" : NumberLong(5)
 },
 "optimeDate" : ISODate("2017-02-07T02:12:14Z"),
 "lastHeartbeat" : ISODate("2017-02-07T02:12:14.489Z"),
 "lastHeartbeatRecv" : ISODate("2017-02-07T02:12:16.438Z"),
 "pingMs" : NumberLong(0),
 "syncingTo" : "10.9.161.130:27017",
 "configVersion" : 19
 },
 {
 "_id" : 6,
 "name" : "10.9.197.6:27017",
 "health" : 1,
 "state" : 3,
 "stateStr" : "RECOVERING",
 "uptime" : 41985,
 "optime" : {
 "ts" : Timestamp(1486391572, 534),
 "t" : NumberLong(5)
 },
 "optimeDate" : ISODate("2017-02-06T14:32:52Z"),
 "maintenanceMode" : 487,
 "infoMessage" : "could not find member to sync from",
 "configVersion" : 19,
 "self" : true
 }
 ],
 "ok" : 1
}
kk-comic-shard01:RECOVERING> rs.printSlaveReplicationInfo()
source: 10.9.184.101:27017
 syncedTo: Tue Feb 07 2017 10:15:24 GMT+0800 (CST)
 0 secs (0 hrs) behind the primary
source: 10.9.197.6:27017
 syncedTo: Mon Feb 06 2017 22:32:52 GMT+0800 (CST)
 42152 secs (11.71 hrs) behind the primary

【问题原因】

主要问题在于新加入的secondary节点最后一个操作时间为“2017-02-06T14:32:52Z”,而主节点的最后一个操作时间为“2017-02-07T02:12:14.489Z”,相差约12小时。这个时间差可能超过了oplog窗口(oplog中第一个和最后一个操作条目之间的时间差)。换句话说,主节点上的操作量太大,导致secondary节点无法赶上。

在初始同步期间,secondary节点同步的是特定时间点的数据。当该时间点的数据被同步后,secondary节点会连接到oplog并应用从该时间点开始的oplog条目中的更改。只要oplog保存了该时间点之间的所有操作,secondary节点就可以正常同步。但是,oplog的大小是有限的,它是一个固定大小的集合。如果在初始同步期间主节点上的操作量超过了oplog能够保存的范围,最早的操作会被删除(“fade out”)。因此,secondary节点无法“构建”与主节点相同的数据,导致同步无法完成,状态一直处于RECOVERY模式。

【解决办法】

根据上述分析,有两种解决办法:

方法一:停止应用,使得主节点不再有新的操作,从而不会使得oplog窗口小于主节点的操作。

方法二:增大oplog的大小。

在不能停库的情况下,显然方法一不适用,因此应选择方法二:增大oplog的大小。

修改oplog大小

方法1:不停服务情况下

参考官档:https://www.php.cn/link/fb02df1865e291f64cc263d80f5ae3a5

  1. Restart a Secondary in Standalone Mode on a Different Port

    1. db.shutdownServer()

    2. 用其他端口以单机模式重新启动该实例,不使用--replSet参数。

    方法一:根据生产环境参数文件设置启动mongo,即将非默认情况参数进行指定。以下参数根据生产参数文件来设置,情况不一:

    /data/servers/app/mongodb-3.2.8/bin/mongod --port 37017 --dbpath /data/servers/data/mg27017/data/ --directoryperdb --wiredTigerDirectoryForIndexes --nojournal &

    该方法较为麻烦,建议选择下面的方法二:

    方法二:将参数文件进行修改:注释replSet部分,修改port为37017,然后以改完后的控制文件来启动mongo。

    /data/servers/app/mongodb-3.2.8/bin/mongod -f /data/servers/data/mg27017/mongod.conf

    下面截图显示的是只要更改的部分,端口号改为任意的没被占用的即可,此处改为37017。

    MongoDB更改oplog大小

    netstat -anp | grep $port查看端口号是否已启动。

    MongoDB更改oplog大小

  2. Create a Backup of the Oplog (Optional)

    在单机模式(非replSet方式)下备份该37017端口已存在的oplog,oplog对应的集合为local数据库下的oplog.rs。下面为具体命令:

    /data/servers/app/mongodb-3.2.8/bin/mongodump --db local --collection 'oplog.rs' --port 37017 --host=127.0.0.1 -uroot -p111111111 --authenticationDatabase=admin -o /data/servers/data/mg27017/dump

    【命令说明】

    • -o(--out)是指定输出目录。该目录需要执行备份的用户拥有相应权限,不用提前创建。
    • --authenticationDatabase是用户名和密码对应的认证数据库,如果环境不需要密码认证,则-u-p--authenticationDatabase不需要指定。
  3. Recreate the Oplog with a New Size and a Seed Entry

    保存oplog中的最后一个条目。

    登陆local数据库:

    use local

    定义对象:db

    db = db.getSiblingDB('local')

    使用temp集合来保存最后一个条目,这个集合保证里面没有数据:db.temp.drop(),在删除前确认下该数据是否可以删除,如果不可以删除,使用另一个集合也是一样的。此处temp没有数据。

    MongoDB更改oplog大小

    睿拓智能网站系统-网上商城
    睿拓智能网站系统-网上商城

    睿拓智能网站系统-网上商城1.0免费版软件大小:5M运行环境:asp+access本版本是永州睿拓信息专为电子商务入门级用户开发的网上电子商城系统,拥有产品发布,新闻发布,在线下单等全部功能,并且正式商用用户可在线提供多个模板更换,可实现一般网店交易所有功能,是中小企业和个人开展个人独立电子商务商城最佳的选择,以下为详细功能介绍:1.最新产品-提供最新产品发布管理修改,和最新产品订单查看2.推荐产

    下载

    使用db.collection.save()方法:找到自然顺序的逆向排序后的最后一个条目,并将其保存到一个临时的集合里面。

    db.temp.save( db.oplog.rs.find( { }, { ts: 1, h: 1 } ).sort( {$natural : -1} ).limit(1).next() )

    插入后结果为:

    MongoDB更改oplog大小

  4. Remove the Existing Oplog Collection

    删除local下的oplog.rs集合,结果返回为true。

    db = db.getSiblingDB('local')
    db.oplog.rs.drop()

    MongoDB更改oplog大小

  5. Create a New Oplog

    创建oplog.rs固定集合,设置大小为4G,该大小根据实际情况来定。

    db.runCommand( { create: "oplog.rs", capped: true, size: (4 * 1024 * 1024 * 1024) } )
  6. Insert the Last Entry of the Old Oplog into the New Oplog

    将之前保存的oplog的最后一个条目插入到新的oplog里。

    db.oplog.rs.save( db.temp.findOne() )

    MongoDB更改oplog大小

    跟temp结果比对是一致的。

  7. Restart the Member

    关闭单机实例,要用admin才能关闭。

    use admin
    db.shutdownServer()

    将之前更改的操作还原,启动mongo。

    /data/servers/app/mongodb-3.2.8/bin/mongod -f /data/servers/data/mg27017/mongod.conf

    查看主从复制状态,确保状态正常。

    db.runCommand( { replSetGetStatus : 1 } ) 或者 rs.status()
  8. Repeat Process for all Members that may become Primary

    对要更改oplog大小的所有secondary成员重复此过程。

  9. Change the Size of the Oplog on the Primary

    对于主库,需要先将主库切成从库,再重复上述oplog调整过程。

    方法一:

    rs.stepDown()

    方法二:

    config=rs.conf()
    config.members[2].priority = 6
    rs.reconfig(config)

    此处数字2为rs.conf()里要变成主库的secondary所在的次序,从0开始算,与id无关。priority数字最大即变成主库。旧的主库调整完后,记得要将priority变为1。

方法2:停服务情况下

该方法操作最为简便,但是需要停服务。具体步骤为:

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

    use admin
    db.shutdownServer()
  2. 删除local数据库下的所有文件(PRIMARY节点)

    rm -rf /data/servers/data/mg27017/local/*
  3. 删除mongo数据目录(secondary)

    如果不确定谁是主库,就mv下数据目录。

    rm -rf /data/servers/data/mg27017/data/*
  4. 修改所有节点配置文件(oplogsize)

    oplogSizeMB: 4096
  5. 重启所有节点mongod

    /data/servers/app/mongodb-3.2.8/bin/mongod -f /data/servers/data/mg27017/mongod.conf

    该方法会导致主库如果异常,没有从库可切换,不建议使用该方式。

【小节】

设置多大的oplog合适呢,可以根据现在数据大小,io和大致的oplog window时间预估一个合适的大小。

rs.printReplicationInfo()
  • log length start to end:当oplog写满时可以理解为时间窗口。
  • oplog last event time:最后一个操作发生的时间。

相关专题

更多
length函数用法
length函数用法

length函数用于返回指定字符串的字符数或字节数。可以用于计算字符串的长度,以便在查询和处理字符串数据时进行操作和判断。 需要注意的是length函数计算的是字符串的字符数,而不是字节数。对于多字节字符集,一个字符可能由多个字节组成。因此,length函数在计算字符串长度时会将多字节字符作为一个字符来计算。更多关于length函数的用法,大家可以阅读本专题下面的文章。

920

2023.09.19

mongodb和mysql的区别
mongodb和mysql的区别

mongodb和mysql的区别:1、数据模型;2、查询语言;3、扩展性和性能;4、可靠性。本专题为大家提供mongodb和mysql的区别的相关的文章、下载、课程内容,供大家免费下载体验。

281

2023.07.18

mongodb启动命令
mongodb启动命令

MongoDB 是一种开源的、基于文档的 NoSQL 数据库管理系统。本专题提供mongodb启动命令的文章,希望可以帮到大家。

250

2023.08.08

MongoDB删除数据的方法
MongoDB删除数据的方法

MongoDB删除数据的方法有删除集合中的文档、删除整个集合、删除数据库和删除指定字段等。本专题为大家提供MongoDB相关的文章、下载、课程内容,供大家免费下载体验。

160

2023.09.19

常用的数据库软件
常用的数据库软件

常用的数据库软件有MySQL、Oracle、SQL Server、PostgreSQL、MongoDB、Redis、Cassandra、Hadoop、Spark和Amazon DynamoDB。更多关于数据库软件的内容详情请看本专题下面的文章。php中文网欢迎大家前来学习。

973

2023.11.02

mongodb有哪些应用领域
mongodb有哪些应用领域

mongodb 的应用领域涵盖广泛,包括内容管理系统、社交媒体、分析、移动应用、物联网、金融科技、医疗保健和广告技术等领域,因其灵活性、可扩展性和易用性而广受欢迎。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

336

2024.04.02

mongodb和redis哪个读取速度快
mongodb和redis哪个读取速度快

redis 的读取速度比 mongodb 更快。原因包括:1. redis 使用简单的键值存储,而 mongodb 存储 json 格式的数据,需要解析和反序列化。2. redis 使用哈希表快速查找数据,而 mongodb 使用 b-tree 索引。因此,redis 在需要高性能读取操作的应用程序中是一个更好的选择。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

480

2024.04.02

mongodb安装失败如何彻底删除
mongodb安装失败如何彻底删除

彻底删除 mongodb 安装失败的步骤:1、停止和禁用 mongodb 服务;2、删除配置文件、数据目录和日志文件;3、删除 mongodb 二进制文件;4、卸载 mongodb 套件(如果通过软件包管理器安装);5、删除 mongodb 用户、组和目录;6、重启系统。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

372

2024.04.02

Java JVM 原理与性能调优实战
Java JVM 原理与性能调优实战

本专题系统讲解 Java 虚拟机(JVM)的核心工作原理与性能调优方法,包括 JVM 内存结构、对象创建与回收流程、垃圾回收器(Serial、CMS、G1、ZGC)对比分析、常见内存泄漏与性能瓶颈排查,以及 JVM 参数调优与监控工具(jstat、jmap、jvisualvm)的实战使用。通过真实案例,帮助学习者掌握 Java 应用在生产环境中的性能分析与优化能力。

0

2026.01.20

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
MongoDB 教程
MongoDB 教程

共17课时 | 2.2万人学习

黑马云课堂mongodb实操视频教程
黑马云课堂mongodb实操视频教程

共11课时 | 3.1万人学习

MongoDB 教程
MongoDB 教程

共42课时 | 25.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号