MongoDB-4 概述
概述
- MongoDB是一个文档型数据库,MongoDB 以 JSON-like 格式(BSON) 存储数据。没有表、模式、SQL或行的概念。
- 支持副本和分片实现靠扩展性
- 分片(Sharding):水平拆分数据,支持海量数据存储和高并发访问。
- 副本集(Replica Set):自动故障转移,保障高可用性(通常 3 节点起步)
数据格式示例
{
"_id": "12345",
"name": "张三",
"age": 30,
"address": {
"city": "北京",
"street": "中关村"
},
"hobbies": ["编程", "篮球"]
}
文档
- 文档是MongoDB中的一个存储单元,由任意数目的键和值组成。相当于传统数据库中的行的概念
- MongoDB要求每个文档必须有唯一标识符,_id,除非为该字段指定某个值,否则MongoDB将自动创建唯一值,默认_id格式是一个Objectld,它是个12字节的唯一标识符
- MongoDB不要求每个文档必须含有相同的字段,也不要求同名的字段有相同类型的值
集合
- 在 MongoDB 中,集合类似于关系型数据库中的表,但具有更灵活的结构。集合用于存储文档
- MongoDB 使用集合对文档进行分组,
- 同一个集合中的文档可以有不同的字段,无需预先定义结构。例如:如下两个文档可以存储在一个集合中,但是这两个文档的结构却不相同
// 文档1(包含 name 和 age)
{ "_id": 1, "name": "张三", "age": 25 }
// 文档2(包含 name 和 email,没有 age)
{ "_id": 2, "name": "李四", "email": "lisi@example.com" }
数据库
- MongoDB 使用数据库对集合进行分组。
- 一个 MongoDB 实例可以承载多个数据库,每个数据库有零个或多个集合。
- 推荐的做法是将单个应用程序的所有数据都存储在同一个数据库中。
- 通过将数据库名称与该库中的集合名称连接起来,可以获得一个完全限定的集合名称,称为命名空间。
admin
- admin 数据库会在身份验证和授权时被使用。几乎所有全局管理命令都必须针对admin数据库来运行(例如:shutdownServer、listDatabases、rs.status()、addShard)
local
- mongodb单个实例的数据会存储在此数据库中。
- local 用于存储复制过程中所使用的数据,例如 oplog.rs(操作日志、replset.election集合存储了与选举相关的数据。
- local 数据库本身不会被复制到其他节点中
config
- config 数据库存储关于每个分片的信息。
- config数据库专门由配置服务器(Config Servers)存储。
- mongos(查询路由器)靠它来知道数据在哪
mongodb数据类型
null、布尔值、字符串、数组、内嵌文档(文档里面套文档)
数值
shell 默认使用 64 位的浮点数来表示数值类型。因此,下面的数值在 shell 中看起来是
“正常”的:
{"x" : 3.14}
{"x" : 3}
对于整数,可以使用 NumberInt 或 NumberLong 类,它们分别表示 4 字节和 8 字节的有符
号整数。
{"x" : NumberInt("3")}
{"x" : NumberLong("3")}
日期
MongoDB 会将日期存储为 64 位整数,表示自 Unix 纪元(1970 年 1 月 1 日)以来的毫
秒数,不包含时区信息。
{"x" : new Date()}
正则表达式
查询时可以使用正则表达式,语法与 JavaScript 的正则表达式语法相同。
{"x" : /foobar/i}
ObjectID
Object ID 是一个 12 字节的 ID,是文档的唯一标识。
{"x" : ObjectId()}
条件操作符

oplog详解
oplog 存储位置
- MongoDB 的 oplog(操作日志)存储在 磁盘 上,而不是内存中。
物理存储:
- oplog 实际上是 local 数据库中的一个特殊 capped collection(固定大小集合)
- 数据持久化存储在磁盘的数据文件中(通常位于 local/oplog.rs 集合)
- 默认存储在 local 数据库对应的数据文件中
内存缓存:
- 为提高性能,MongoDB 会缓存部分活跃的 oplog 条目在内存中(通过 WiredTiger 存储引擎的缓存机制)
- 但这只是性能优化,oplog 的权威数据始终在磁盘上
- 如果系统内存不足,可能影响 oplog 的缓存效果,但不会导致 oplog 数据丢失,只是性能下降
- 写入先进入内存缓冲区,然后定期刷写到磁盘(默认60秒间隔,或每100MB写入)
- 频繁访问的 oplog 条目会被缓存到内存。这显著提高了副本集成员同步的速度
查看 oplog 信息
- 查看 oplog 大小和状态:
rs.printReplicationInfo()
输出示例:
configured oplog size: 1024MB
oplog first event time: Thu Oct 05 2023 10:00:00 GMT+0800 (CST)
oplog last event time: Thu Oct 05 2023 16:00:00 GMT+0800 (CST)
- 直接查询 oplog 集合:
use local
db.oplog.rs.find().limit(1)
oplog配置建议
- 对于高写入负载的系统,oplog 应足够大(通常建议能保存两到三天的操作)
- 默认的 oplog 大小(空闲磁盘空间的5%)可能不适合生产环境
# 启动时指定 oplog 大小(MB)
mongod --replSet myReplSet --oplogSize 2048
# 或运行时调整:
db.adminCommand({replSetResizeOplog: 1, size: 1024*1024*1024}) // 1GB
选举详解
MongoDB 副本集中节点成为主节点(Primary)的资格条件
- 在 MongoDB 副本集中,一个节点要成为主节点,必须满足以下条件:
- 必须是数据节点(不能是仲裁者或隐藏节点)
- 优先级(priority)大于0(默认所有数据节点priority=1)
- 状态必须为"SECONDARY"(运行正常的从节点)
- 拥有最新的数据集(与大多数节点同步)
选举过程中的评估标准
- 当触发选举时,候选节点还需满足:
oplog足够新:
- 候选节点的oplog必须比其他大多数节点的oplog更新或同等新
- 通过比较optime(操作时间戳)判断
与多数节点连通:
- 能与副本集中大多数节点建立连接
- 包括仲裁者(仲裁者也参与投票)
未被禁止选举:
- 没有被配置为priority: 0(永远不能成为主节点)
- 没有被设置为hidden: true(隐藏节点)
选举权重因素
- 当多个节点符合基本条件时,按以下顺序决定:
- 优先级(priority)值(数值越高越优先)
- optime新旧(操作日志越新越优先)
- 节点_id值(数字越小越优先,作为最后比较条件)
回滚
什么是回滚
- 当 MongoDB 副本集发生主节点切换时,原主节点上已写入但未同步到多数从节点的操作会被撤销,这个过程称为回滚(Rollback)。
触发回滚的条件
主节点宕机后重新加入副本集
网络分区导致原主节点失去多数连接
人工强制切换主节点(rs.stepDown())
原主节点上有未被多数从节点复制的写操作
回滚过程
节点检测到自己需要回滚(状态变为ROLLBACK)
确定需要回滚的操作点(lastOpTime和commonPoint)
撤销未被复制的写操作
从当前主节点重新同步数据
完成后重新加入副本集作为从节点
回滚数据保存
MongoDB 会将回滚的数据保存为 BSON 文件:
<dbpath>/rollback/
├── <collection>.<timestamp>.0.bson
├── <collection>.<timestamp>.1.bson
└── ...
查看回滚信息
javascript
// 检查是否有待处理的回滚数据
db.adminCommand({getCmdLineOpts: 1}).parsed.storage.dbPath + "/rollback"
// 查看回滚状态
rs.status().members.filter(m => m.stateStr === "ROLLBACK")
减少回滚风险的方法
写关注(Write Concern)使用"majority"
javascript
db.products.insert(
{ item: "card", qty: 15 },
{ writeConcern: { w: "majority" } }
)
配置更大的oplog窗口
javascript
db.adminCommand({replSetResizeOplog: 1, size: 1024*1024*1024}) // 1GB
监控复制延迟
javascript
rs.printSlaveReplicationInfo()
避免长时间的网络分区
处理回滚数据
使用mongorestore恢复回滚数据:
bash
mongorestore --db dbname /data/db/rollback/{collection}.{timestamp}.bson
手动审查并重新应用重要操作
重要注意事项
回滚可能导致数据丢失(未被复制的操作)
回滚操作是自动进行的,无需人工干预
大事务可能导致长时间回滚
频繁回滚可能表明系统配置有问题

浙公网安备 33010602011771号