Mongodb oplog的作用及如何评估和更改保留时间

作者介绍:老苏,10余年DBA工作运维经验,擅长Oracle、MySQL、PG数据库运维(如安装迁移,性能优化、故障应急处理等)
公众号:老苏畅谈运维
欢迎关注本人公众号,更多精彩与您分享。

oplog 是replica set或者master/slave模式专用,在replica set中oplog是一个定容集合(capped collection),其实就是一张表,它的默认大小是磁盘空间的5%(可以通过–oplogSizeMB参数修改)。
位于local库的db.oplog.rs,有兴趣可以看看里面到底有些什么内容。其中记录的是整个mongod实例一段时间内数据库的所有变更(插入/更新/删除)操作。
当空间用完时新记录自动覆盖最老的记录。其覆盖范围被称作oplog时间窗口。
需要注意的是,因为oplog是一个定容集合,所以时间窗口能覆盖的范围会因为你单位时间内的更新次数不同而变化。

1、查看oplog的内容

use local
db.oplog.rs.find().pretty()
在这里插入图片描述
主要需要关注的字段:

"ts" : Timestamp(1553597844, 1) <----操作时间
"op" : "n"                      <----操作类型
 ns:                            <----操作所在的namespace
 o:                             <----操作所对应的document,即当前操作的内容(比如更新操作时要更新的的字段和值)
 o2:                             <---在执行更新操作时的where条件,仅限于update时才有该属性

关于op操作类型主要有:

    "i": insert
    "u": update
    "d": delete
    "c": db cmd
	"db":声明当前数据库 (其中ns 被设置成为=>数据库名称+ '.')
    "n": no op,即空操作,其会定期执行以确保时效性

2、oplog查找方法

如何oplog保留时间较长,查找不便,如何进行过滤?以下是一些常用的查找方法:
–只显示insert操作
db.oplog.rs.find({“op”:“i”}).pretty()

–显示数据库相关操作
db.oplog.rs.find({“op”:“c”}).pretty()

–查询oplog里的insert记录,对应op为i的记录:
db.oplog.rs.find({“op” : “i”}).pretty().limit(3)

–查update操作命令:
db.oplog.rs.find({“op” : “u”}).pretty().limit(3)

–查delete操作命令:
db.oplog.rs.find({“op” : “d”}).pretty().limit(3)

–根据时间范围查操作:
db.oplog.rs.find({“o.createTime”: {$gte:new Date(2024,6,29)}}).limit(3)

–查时间段的操作记录:
db.oplog.rs.find({“o.createTime”: { g t e : n e w D a t e ( 2024 , 6 , 29 ) , gte:new Date(2024,6,29), gte:newDate(2024,6,29),lte:new Date(2024,7,2)}}).limit(3)

我们查查对dbtest.students集合进行操作的所有的 oplog 记录
db.oplog.rs.find({ns : “dbtest.students”})

–将oplog.rs重新创建为一个无上限的集合(会一直保留,慎用)
db.runCommand( { create: “oplog.rs”, capped: false})

–将oplog备份(转储)到文件夹 YYYYMMDD:
mongodump -u root -p 123456 --authenticationDatabase=admin --db local --collection oplog.rs -o /media/backup/$(date +%Y%m%d)

3、如何评估oplog保留大小

如果oplog 设置太大,保留时间过长,查找起来不方便。生产上建议保留个三四天,每天做一下备份。那如何进行oplog保留大小呢?

rs1 [direct: primary] local> rs.printReplicationInfo();
actual oplog size
'4096 MB'               <------当前实际值
---
configured oplog size  <--集合大小
'4096 MB'
---
log length start to end
'491682 secs (136.58 hrs)'      <--预计窗口覆盖时间
---
oplog first event time
'Sat Jun 29 2024 22:11:01 GMT+0800 (China Standard Time)'
---
oplog last event time
'Fri Jul 05 2024 14:45:43 GMT+0800 (China Standard Time)'
---
now
'Fri Jul 05 2024 14:45:46 GMT+0800 (China Standard Time)'

根据预计窗口覆盖时间,可以调整oplog大小,那么如何进行调整大小呢?
如果你的MongoDB版本为4.0以后的版本,可以直接使用replSetResizeOplog修改。

(1)查看oplog大小

rs1 [direct: primary] local> db.getReplicationInfo()
{
  configuredLogSizeMB: 4096,
  logSizeMB: 4096,
  usedMB: 16.06,
  timeDiff: 565687,
  timeDiffHours: 157.14,
  tFirst: 'Sat Jun 29 2024 22:23:17 GMT+0800 (China Standard Time)',
  tLast: 'Sat Jul 06 2024 11:31:24 GMT+0800 (China Standard Time)',
  now: 'Sat Jul 06 2024 11:31:24 GMT+0800 (China Standard Time)'
}

(2)修改oplog大小

rs1 [direct: primary] local> db.adminCommand({replSetResizeOplog:1,size:6144})
{
  ok: 1,
  '$clusterTime': {
    clusterTime: Timestamp({ t: 1720236744, i: 1 }),
    signature: {
      hash: Binary.createFromBase64('6GGIXAYyqPZI8nDe2XJP0jjjS4c=', 0),
      keyId: Long('7385858098457477126')
    }
  },
  operationTime: Timestamp({ t: 1720236744, i: 1 })
}

(3)验证oplog大小

rs1 [direct: primary] local> db.getReplicationInfo()
{
  configuredLogSizeMB: 6144,
  logSizeMB: 6144,
  usedMB: 16.06,
  timeDiff: 565797,
  timeDiffHours: 157.17,
  tFirst: 'Sat Jun 29 2024 22:23:17 GMT+0800 (China Standard Time)',
  tLast: 'Sat Jul 06 2024 11:33:14 GMT+0800 (China Standard Time)',
  now: 'Sat Jul 06 2024 11:33:14 GMT+0800 (China Standard Time)'
}

在这里插入图片描述

关注我,学习更多的数据库知识
请添加图片描述

要统计 MongoDB Oplog 中各表项数据,可以使用以下步骤: 1. 连接到 MongoDB 数据库,并打开 Oplog。 2. 执行一个聚合查询来获取 Oplog 中所有操作的列表。可以使用 `$match` 过滤出指定时间范围内的操作。 3. 对于每一个操作,获取操作的名称和操作涉及的表格名称。可以从操作的 `op` 字段中获取操作名称,从操作的 `ns` 字段中获取表格名称。 4. 对于每一个表格,统计其涉及的操作数量。可以使用 `$group` 聚合操作来实现。 以下是一个示例代码,可以帮助你实现这个过程: ```python from pymongo import MongoClient # 连接到 MongoDB 数据库 client = MongoClient('mongodb://localhost:27017/') # 打开 Oplog oplog = client.local.oplog.rs # 聚合查询,获取 Oplog 中所有操作的列表 query = [ {"$match": {"ts": {"$gt": 1614556800, "$lt": 1617158400}}}, {"$project": {"_id": 0, "op": 1, "ns": 1}} ] cursor = oplog.aggregate(query) # 统计每一个表格涉及的操作数量 table_ops = {} for doc in cursor: op = doc["op"] table = doc["ns"].split(".", 1)[1] if table not in table_ops: table_ops[table] = {} if op not in table_ops[table]: table_ops[table][op] = 0 table_ops[table][op] += 1 # 打印结果 for table, ops in table_ops.items(): print(table) for op, count in ops.items(): print(f" {op}: {count}") ``` 在上面的代码中,我们首先连接到 MongoDB 数据库,并打开 Oplog。然后执行了一个聚合查询,获取指定时间范围内 Oplog 中所有操作的列表。接下来,我们对每一个操作,获取操作的名称和操作涉及的表格名称,并统计每一个表格涉及的操作数量。最后,我们打印了结果,以便查看每一个表格的操作数量。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

老苏畅谈运维

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值