MongoDB 运维维护手册
面向 DBA / 运维工程师,聚焦生产环境的部署架构、监控告警、性能调优、备份恢复、故障排查、容量规划与版本升级。所有命令均基于 MongoDB 7.0 + CentOS 7 + Docker 环境。
目录
- 生产部署架构选型
- Docker 部署形态(单机/副本集/分片集群)
- 监控体系搭建
- 性能调优
- 备份与恢复
- 安全加固
- 日志管理
- 副本集运维操作
- 容量规划
- 版本升级与回滚
- 故障排查手册
- 应急预案
- 日常巡检清单
1. 生产部署架构选型
| 架构 | 适用场景 | 节点数 | 高可用 | 水平扩展 | 运维复杂度 |
|---|---|---|---|---|---|
| 单机 | 开发/测试 | 1 | 无 | 无 | 低 |
| 副本集 (Replica Set) | 中小规模生产 | 3+ | 有 | 无 | 中 |
| 分片集群 (Sharded Cluster) | 大数据量/高并发 | 9+ | 有 | 有 | 高 |
选型决策
- 数据量 < 500GB,QPS < 5000 → 副本集(3 节点)
- 数据量 500GB-3TB,单集合写入瓶颈 → 分片集群
- 数据量 > 3TB → 必须分片
副本集 vs 分片集群核心区别
- 副本集:所有节点存全量数据,解决"高可用",不解决"容量"
- 分片集群:数据分散到多个 shard,每个 shard 是副本集,同时解决"高可用 + 容量"
生产环境最低标准:3 节点副本集(1 Primary + 2 Secondary),可容忍 1 节点故障。
2. Docker 部署形态
本节覆盖三种部署形态,按数据量和可用性需求递进:单机(测试)→ 副本集(生产标准)→ 分片集群(大数据量)。
| 形态 | 节点数 | 高可用 | 水平扩展 | 适用 |
|---|---|---|---|---|
| 单机 | 1 | 无 | 无 | 开发/测试/学习 |
| 副本集 | 3+ | 有 | 无 | 中小规模生产 |
| 分片集群 | 10+ | 有 | 有 | 大数据量/高并发 |
2.1 单机部署(开发/测试)
仅用于开发/测试/学习。生产环境禁止单机——无高可用、无数据冗余,宕机即丢服务,且无法做 point-in-time 恢复。
docker-compose 配置
# /data/mongo/standalone/docker-compose.yml
version: "3.8"
services:
mongodb:
image: mongo:7.0
container_name: mongodb
restart: always
ports:
- "27017:27017"
environment:
MONGO_INITDB_ROOT_USERNAME: root
MONGO_INITDB_ROOT_PASSWORD: YourStrongPassword123
volumes:
- /data/mongo/standalone/db:/data/db
- /data/mongo/standalone/config:/data/configdb
- /data/mongo/standalone/log:/var/log/mongodb
command:
- "--bind_ip_all"
- "--auth"
- "--wiredTigerCacheSizeGB=2" # 建议: 容器内存的 50-60%
deploy:
resources:
limits:
memory: 4G
networks:
- mongo-net
networks:
mongo-net:
driver: bridge
启动与连接
# 创建目录
mkdir -p /data/mongo/standalone/{db,config,log}
# 启动
cd /data/mongo/standalone
docker compose up -d
# 查看状态
docker ps | grep mongodb
docker logs mongodb
# 进入 shell
docker exec -it mongodb mongosh -u root -p YourStrongPassword123
# 远程连接
mongosh "mongodb://root:YourStrongPassword123@服务器IP:27017/admin"
单机运维注意
- 无故障转移:mongod 进程挂掉即服务中断,依赖
restart: always自动拉起 - 备份限制:只能用
mongodump(无 oplog,不能加--oplog,不能恢复到任意时间点) - 可平滑升级为副本集:加
--replSet参数重启 →rs.initiate()→ 再加入其他节点 - 数据量建议 < 10GB:超过建议直接上副本集
- 监控仍需开启:单机也要监控连接数、内存、磁盘,参考第 3 节
2.2 副本集部署(生产标准)
生产环境最低标准:3 节点(1 Primary + 2 Secondary),可容忍 1 节点故障,自动故障转移。
2.2.1 docker-compose 部署 3 节点副本集
# /data/mongo/compose/docker-compose.yml
version: "3.8"
services:
mongo1:
image: mongo:7.0
container_name: mongo1
restart: always
hostname: mongo1
ports:
- "27017:27017"
environment:
MONGO_INITDB_ROOT_USERNAME: root
MONGO_INITDB_ROOT_PASSWORD: YourStrongPassword123
volumes:
- /data/mongo/node1/db:/data/db
- /data/mongo/node1/config:/data/configdb
- /data/mongo/node1/log:/var/log/mongodb
command: ["--replSet", "rs0", "--bind_ip_all", "--auth"]
networks:
- mongo-net
mongo2:
image: mongo:7.0
container_name: mongo2
restart: always
hostname: mongo2
ports:
- "27018:27017"
environment:
MONGO_INITDB_ROOT_USERNAME: root
MONGO_INITDB_ROOT_PASSWORD: YourStrongPassword123
volumes:
- /data/mongo/node2/db:/data/db
- /data/mongo/node2/config:/data/configdb
- /data/mongo/node2/log:/var/log/mongodb
command: ["--replSet", "rs0", "--bind_ip_all", "--auth"]
networks:
- mongo-net
mongo3:
image: mongo:7.0
container_name: mongo3
restart: always
hostname: mongo3
ports:
- "27019:27017"
environment:
MONGO_INITDB_ROOT_USERNAME: root
MONGO_INITDB_ROOT_PASSWORD: YourStrongPassword123
volumes:
- /data/mongo/node3/db:/data/db
- /data/mongo/node3/config:/data/configdb
- /data/mongo/node3/log:/var/log/mongodb
command: ["--replSet", "rs0", "--bind_ip_all", "--auth"]
networks:
- mongo-net
networks:
mongo-net:
driver: bridge
2.2.2 初始化副本集
# 启动所有节点
cd /data/mongo/compose
docker compose up -d
# 进入 mongo1 初始化副本集
docker exec -it mongo1 mongosh -u root -p YourStrongPassword123
// 初始化副本集(需用容器名,因为是 Docker 网络)
rs.initiate({
_id: "rs0",
members: [
{ _id: 0, host: "mongo1:27017", priority: 2 },
{ _id: 1, host: "mongo2:27017", priority: 1 },
{ _id: 2, host: "mongo3:27017", priority: 1 }
]
})
// 查看副本集状态
rs.status()
// 查看是否已选出 Primary
rs.isMaster()
2.2.3 创建业务管理员账号
初始化副本集后,在 Primary 上创建:
use admin
db.createUser({
user: "admin",
pwd: "AdminStrongPassword456",
roles: [{ role: "root", db: "admin" }]
})
2.2.4 连接副本集(推荐)
# 连接字符串带 replicaSet 参数
mongosh "mongodb://root:YourStrongPassword123@mongo1:27017,mongo2:27017,mongo3:27017/admin?replicaSet=rs0"
# 应用程序连接串(驱动会自动发现所有节点,故障时自动切换)
mongodb://user:pass@mongo1:27017,mongo2:27017,mongo3:27017/mydb?replicaSet=rs0&authSource=admin
关键:连接串必须列出多个节点,驱动才能在 Primary 切换后自动重连新 Primary。
2.3 分片集群部署(大数据量)
当单库数据 > 3TB、单集合 > 500GB、或单机写入 QPS 扛不住时,需用分片集群水平扩展。每个 shard 内部本身就是副本集,兼顾高可用与扩展性。
2.3.1 组件说明
| 组件 | 作用 | 数量 | 说明 |
|---|---|---|---|
| mongos | 路由入口 | ≥2(生产) | 应用只连 mongos,不直连 shard |
| config server | 元数据 & 路由表 | 3(副本集) | 记录 chunk 分布,必须高可用 |
| shard | 存数据 | ≥2(各为副本集) | 每个 shard 是独立副本集 |
本节部署最小可用分片集群:1 mongos + 1 config-rs(3节点) + 2 shard-rs(各3节点) = 10 个容器。
2.3.2 docker-compose 配置
完整配置见独立文件 mongo-sharded-docker-compose.yml,核心结构:
# config server(3 节点副本集,端口 27019)
cfg1/cfg2/cfg3:
command: ["--configsvr", "--replSet", "cfgReplSet", "--bind_ip_all", "--auth"]
# shard(每个 3 节点副本集,端口 27018)
shard1a/1b/1c:
command: ["--shardsvr", "--replSet", "shard1ReplSet", "--bind_ip_all", "--auth"]
shard2a/2b/2c:
command: ["--shardsvr", "--replSet", "shard2ReplSet", "--bind_ip_all", "--auth"]
# mongos 路由(端口 27017)
mongos:
command: ["--configdb", "cfgReplSet/cfg1:27019,cfg2:27019,cfg3:27019", "--bind_ip_all"]
关键启动参数:
--configsvr(标记为配置服务器)、--shardsvr(标记为分片节点)。mongos 不存数据,通过--configdb指向 config 副本集。
2.3.3 初始化分片集群
# 0. 创建目录并启动
mkdir -p /data/mongo/sharded/{cfg1,cfg2,cfg3,shard1a,shard1b,shard1c,shard2a,shard2b,shard2c}/{db,config}
cp mongo-sharded-docker-compose.yml /data/mongo/sharded/docker-compose.yml
cd /data/mongo/sharded
docker compose up -d
sleep 10 # 等待节点就绪
# 1. 初始化 config server 副本集(在 cfg1 执行)
docker exec cfg1 mongosh -u root -p YourStrongPassword123 \
--authenticationDatabase admin --eval '
rs.initiate({
_id: "cfgReplSet",
configsvr: true,
members: [
{ _id: 0, host: "cfg1:27019" },
{ _id: 1, host: "cfg2:27019" },
{ _id: 2, host: "cfg3:27019" }
]
})
'
# 2. 初始化 shard1 副本集(在 shard1a 执行)
docker exec shard1a mongosh -u root -p YourStrongPassword123 \
--authenticationDatabase admin --eval '
rs.initiate({
_id: "shard1ReplSet",
members: [
{ _id: 0, host: "shard1a:27018" },
{ _id: 1, host: "shard1b:27018" },
{ _id: 2, host: "shard1c:27018" }
]
})
'
# 3. 初始化 shard2 副本集(在 shard2a 执行)
docker exec shard2a mongosh -u root -p YourStrongPassword123 \
--authenticationDatabase admin --eval '
rs.initiate({
_id: "shard2ReplSet",
members: [
{ _id: 0, host: "shard2a:27018" },
{ _id: 1, host: "shard2b:27018" },
{ _id: 2, host: "shard2c:27018" }
]
})
'
sleep 15 # 等待所有副本集选出 Primary
# 4. 连接 mongos,添加分片到集群
docker exec mongos mongosh --eval '
sh.addShard("shard1ReplSet/shard1a:27018,shard1b:27018,shard1c:27018")
sh.addShard("shard2ReplSet/shard2a:27018,shard2b:27018,shard2c:27018")
sh.status()
'
2.3.4 启用分片
// 连接 mongos
// docker exec -it mongos mongosh
// 1. 对数据库启用分片
sh.enableSharding("mydb")
// 2. 选择 shard key(至关重要!选错无法更改)
// 原则: 高基数(值多) + 低频率(分布均匀) + 非单调递增
// 常用: hashed 分片(均匀打散)或 ranged 分片(范围查询友好)
// 3. 对集合分片前,必须先建索引
use mydb
db.orders.createIndex({ userId: "hashed" }) // hashed 分片
// 或 db.orders.createIndex({ createdAt: 1 }) // ranged 分片
// 4. 启用集合分片
sh.shardCollection("mydb.orders", { userId: "hashed" })
// 5. 查看分片状态 & 数据分布
sh.status()
db.orders.getShardDistribution()
2.3.5 连接分片集群
# 应用只连 mongos(端口 27017),绝不直连 shard
mongosh "mongodb://服务器IP:27017/mydb"
# 带认证
mongosh "mongodb://user:pass@服务器IP:27017/mydb?authSource=admin"
# 生产多 mongos 连接串(故障自动切换)
mongodb://mongos1:27017,mongos2:27017/mydb
2.3.6 分片集群运维要点
// 集群状态总览
sh.status() // 所有 shard、chunk 分布
sh.balancer.status() // 均衡器状态
sh.isBalancerRunning() // 均衡器是否在迁移 chunk
// 维护窗口暂停均衡(避免迁移影响性能)
sh.disableBalancing() // 暂停
sh.enableBalancing() // 恢复
sh.setBalancerState(false) // 同上
// 集合分布详情
db.orders.getShardDistribution() // 各 shard 数据量
db.orders.stats().sharded // 是否已分片
// 添加新分片(扩容)
sh.addShard("shard3ReplSet/shard3a:27018,shard3b:27018,shard3c:27018")
// 添加后均衡器自动迁移 chunk 到新 shard
// 移除分片(会先迁移数据,耗时)
db.adminCommand({ removeShard: "shard2ReplSet" })
// 反复执行直到返回 completed,期间可查迁移进度
shard key 选择是分片集群最关键的决策:
- 选错会导致数据倾斜(个别 shard 过载)或 jumbo chunk
- MongoDB 5.0 起支持refineCollectionShardKey微调,但不能完全更换
- 4.4 之前完全无法更改,只能新建集合迁移数据
- 推荐:{ userId: "hashed" }(高基数、均匀)或{ _id: "hashed" }何时分片:先确认瓶颈是"容量"还是"性能"。如果是单集合查询慢,优先加索引;如果是连接数/CPU 瓶颈,先升级硬件。分片解决的是水平扩展,不是万能药。
2.4 三种部署形态对照
| 维度 | 单机 | 副本集 | 分片集群 |
|---|---|---|---|
| 节点数 | 1 | 3+ | 10+ |
| 高可用 | 无(进程级 restart) | 自动故障转移 10-30s | shard 级故障转移 |
| 数据冗余 | 无 | 全量复制 | 分片内全量复制 |
| 容量上限 | 单机磁盘 | 单机磁盘 ×1 | 理论无限 |
| 写扩展性 | 单点 | 单 Primary 写 | 多 shard 并行写 |
| 备份方式 | mongodump | mongodump --oplog / 快照 | 每 shard 独立备份 / mongodump |
| Point-in-time 恢复 | 不支持 | 支持(oplog) | 支持(每 shard 的 oplog) |
| 运维复杂度 | 低 | 中 | 高 |
| 适用阶段 | 开发测试 | 中小生产 | 大数据量生产 |
| 升级路径 | → 副本集 | → 分片集群 | - |
建议路径:测试用单机 → 生产上副本集 → 数据量增长后分片。可平滑升级,无需推倒重来。
3. 监控体系搭建
3.1 核心监控指标(必看)
| 维度 | 指标 | 获取方式 | 告警阈值 |
|---|---|---|---|
| 连接数 | current connections | serverStatus().connections.current |
> maxConn × 80% |
| 内存 | cache hit ratio | wiredTiger.cache 计算 |
< 95% |
| 内存 | pages evicted | wiredTiger.cache.evicted |
持续增长告警 |
| 复制 | replication lag | rs.printSecondaryReplicationInfo() |
> 10s |
| 复制 | node state | rs.status() 中 stateStr |
非 PRIMARY/SECONDARY |
| 性能 | slow queries | profile 集合 / logs | > 100ms |
| 性能 | active connections | serverStatus().globalLock.activeClients |
> 1000 |
| 磁盘 | disk usage | df -h |
> 80% |
| 磁盘 | disk IOPS | iostat -x 1 |
util > 90% |
| 队列 | read/write queue | serverStatus().globalLock.currentQueue |
持续 > 0 |
3.2 关键诊断命令
服务器整体状态
// 完整服务器状态(输出很大)
db.serverStatus()
// 精简查看关键指标
db.serverStatus().connections
db.serverStatus().opcounters // 各操作 QPS
db.serverStatus().globalLock // 锁和队列
db.serverStatus().wiredTiger.cache // 缓存
db.serverStatus().mem // 内存
db.serverStatus().metrics.query // 查询统计
// 当前版本和运行时间
db.serverStatus().version
db.serverStatus().uptime
副本集状态
// 副本集完整状态
rs.status()
// 简洁版:各节点延迟
rs.printSecondaryReplicationInfo()
// oplog 信息(窗口大小很重要)
rs.printReplicationInfo()
// 是否是 Primary
rs.isMaster()
当前活跃操作
// 查看所有活跃操作
db.currentOp({ active: true })
// 只看运行超过 1 秒的操作
db.currentOp({
active: true,
secs_running: { $gte: 1 }
})
// 杀掉指定操作
db.killOp("opid")
慢查询分析
// 开启慢查询日志(记录 > 100ms 的操作)
db.setProfilingLevel(1, { slowms: 100 })
// 查看级别
db.getProfilingStatus()
// 查看慢查询记录(存在 system.profile 集合)
db.system.profile.find().sort({ ts: -1 }).limit(10)
// 查询最慢的 5 个操作
db.system.profile.find()
.sort({ millis: -1 })
.limit(5)
.forEach(op => printjson({
op: op.op,
ns: op.ns,
millis: op.millis,
query: op.command
}))
3.3 监控方案选型
| 方案 | 说明 | 适用 |
|---|---|---|
| MongoDB Cloud Monitor | 官方免费,需联网上报 | 云上/可联网 |
| Prometheus + Grafana | mongodb_exporter 采集 | 自建机房推荐 |
| Percona PMM | 开源数据库监控平台 | 多种数据库混合 |
| Zabbix + 自定义脚本 | 传统运维已有 Zabbix | 已有 Zabbix 体系 |
Prometheus + mongodb_exporter 部署
# 在 docker-compose 中加入 exporter
mongo-exporter:
image: percona/mongodb_exporter:latest
container_name: mongo-exporter
restart: always
ports:
- "9216:9216"
environment:
MONGODB_URI: "mongodb://root:YourStrongPassword123@mongo1:27017/admin?authSource=admin"
depends_on:
- mongo1
networks:
- mongo-net
Grafana 推荐仪表盘 ID:7353(MongoDB Overview)、16490(副本集详情)。
3.4 告警规则示例(Prometheus AlertManager)
groups:
- name: mongodb
rules:
- alert: MongoDBDown
expr: mongodb_up == 0
for: 1m
labels:
severity: critical
annotations:
summary: "MongoDB 实例宕机"
- alert: MongoDBReplicationLag
expr: mongodb_rs_members_replication_lag > 10
for: 2m
labels:
severity: warning
annotations:
summary: "复制延迟超过 10 秒"
- alert: MongoDBConnectionsHigh
expr: mongodb_ss_connections{conn_type="current"} / on(instance) mongodb_ss_connections{conn_type="available"} > 0.8
for: 5m
labels:
severity: warning
annotations:
summary: "连接数超过 80%"
- alert: MongoDBDiskSpaceLow
expr: (1 - node_filesystem_avail_bytes / node_filesystem_size_bytes) > 0.8
for: 5m
labels:
severity: warning
annotations:
summary: "磁盘使用率超过 80%"
4. 性能调优
4.1 WiredTiger 存储引擎调优
WiredTiger 是 MongoDB 3.2+ 默认引擎,核心参数是缓存大小。
// 查看当前缓存配置
db.serverStatus().wiredTiger.cache
// 关键指标:
// "maximum bytes configured" - 配置的最大缓存
// "bytes currently in the cache" - 当前使用
// "pages evicted by application threads" - 应用线程触发的驱逐(高则内存不足)
通过启动参数调整缓存
# docker-compose command 中加入
command:
- "--replSet"
- "rs0"
- "--bind_ip_all"
- "--auth"
- "--wiredTigerCacheSizeGB=4" # 建议: 物理内存的 50%-60%
经验值:缓存 = 物理内存 × 0.6。留 30% 给操作系统文件缓存,10% 给其他进程。
4.2 索引优化
索引使用分析
// 查看集合所有索引
db.users.getIndexes()
// 索引大小(评估内存占用)
db.users.stats().indexSizes
// 分析查询是否走索引
db.users.find({ name: "张三" }).explain("executionStats")
// 关键看:
// winningPlan.stage = "IXSCAN" → 走索引(好)
// winningPlan.stage = "COLLSCAN" → 全表扫描(坏)
// executionStats.totalDocsExamined → 扫描文档数
// executionStats.nReturned → 返回文档数
// 理想: totalDocsExamined ≈ nReturned
索引设计原则
// 1. ESR 原则: Equality(等值) > Sort(排序) > Range(范围)
// 复合索引字段顺序按 E-S-R 排列
db.orders.createIndex({ status: 1, createdAt: -1, amount: 1 })
// status 等值查询, createdAt 排序, amount 范围查询
// 2. 覆盖索引(查询字段全在索引里,无需回表)
db.users.createIndex({ name: 1, age: 1, email: 1 })
db.users.find({ name: "张三" }, { age: 1, email: 1, _id: 0 })
// 此查询被索引覆盖,不读文档
// 3. 删除未使用索引(写入有开销)
db.users.aggregate([{ $indexStats: {} }])
// 查看各索引使用次数,删除使用为 0 的
4.3 慢查询治理
// 1. 开启 profile
db.setProfilingLevel(1, { slowms: 100, sampleRate: 1 })
// 2. 定期分析 TOP 10 慢查询
db.system.profile.aggregate([
{ $group: {
_id: { op: "$op", ns: "$ns", query: "$command" },
count: { $sum: 1 },
avgMillis: { $avg: "$millis" },
maxMillis: { $max: "$millis" }
}},
{ $sort: { avgMillis: -1 } },
{ $limit: 10 }
])
// 3. 生产环境 profile 集合会增长,定期清理
db.system.profile.drop()
db.setProfilingLevel(1, { slowms: 100 })
4.4 连接池优化
# mongod.conf 或启动参数
net:
maxIncomingConnections: 20000 # 默认 65535,按需调小防过载
# 应用端连接池(以 Node.js 驱动为例)
# maxPoolSize: 100 (默认)
# minPoolSize: 10
# maxIdleTimeMS: 30000
经验:单个 mongod 实例 maxPoolSize 建议 100-200,不要无限大。连接数过多会消耗内存和上下文切换。
4.5 系统层面优化
# 1. 文件描述符限制(重要)
cat >> /etc/security/limits.conf <<'EOF'
* soft nofile 65535
* hard nofile 65535
* soft nproc 65535
* hard nproc 65535
EOF
# 2. 关闭透明大页(THP,MongoDB 推荐 disabled)
echo never > /sys/kernel/mm/transparent_hugepage/enabled
echo never > /sys/kernel/mm/transparent_hugepage/defrag
# 持久化(重启生效)
cat >> /etc/rc.local <<'EOF'
echo never > /sys/kernel/mm/transparent_hugepage/enabled
echo never > /sys/kernel/mm/transparent_hugepage/defrag
EOF
chmod +x /etc/rc.local
# 3. 文件系统推荐 XFS(优于 ext4)
# 4. 磁盘调度器推荐 deadline / noop(SSD)
# 5. 关闭 atime 挂载选项
mount -o remount,noatime /data
4.6 Docker 容器特殊注意
# 1. 限制容器内存,防止 OOM 影响其他服务
deploy:
resources:
limits:
memory: 8G
# 2. WiredTiger 缓存要小于容器内存限制
# 容器 8G → 缓存设 4G (--wiredTigerCacheSizeGB=4)
# 3. 数据目录用 bind mount 而非 volume,性能更好
volumes:
- /data/mongo/node1/db:/data/db
# 4. 网络用 host 模式可减少一层 NAT(仅单机时)
# network_mode: "host"
5. 备份与恢复
5.1 备份方案对比
| 方案 | 优点 | 缺点 | 适用 |
|---|---|---|---|
| mongodump | 简单、跨版本 | 慢、占空间、非一致性快照 | 小库 < 50GB |
| 文件系统快照 | 快、一致性好 | 需 LVM/云盘快照 | 大库首选 |
| 文件拷贝 | 快 | 需停 db.lockDown | 应急 |
| oplog 增量 | 可恢复到任意时间点 | 需配合全量 | 精细恢复 |
5.2 mongodump 备份(小库)
# 全量备份(指定副本集,从 Secondary 读减少 Primary 压力)
docker exec mongo2 mongodump \
-u root -p YourStrongPassword123 \
--authenticationDatabase admin \
--oplog \
--gzip \
--archive=/data/backup/full_$(date +%Y%m%d).gz
# 复制到宿主机
docker cp mongo2:/data/backup/full_$(date +%Y%m%d).gz /data/mongo/backup/
# 单库备份
docker exec mongo2 mongodump \
-u root -p YourStrongPassword123 \
--authenticationDatabase admin \
-d mydb \
--gzip \
--out=/data/backup/mydb_$(date +%Y%m%d)
# 单集合备份
docker exec mongo2 mongodump \
-u root -p YourStrongPassword123 \
--authenticationDatabase admin \
-d mydb -c users \
--gzip \
--out=/data/backup/users_$(date +%Y%m%d)
关键参数
--oplog:记录备份期间的 oplog,恢复时能保证一致性(仅副本集可用)。
5.3 mongorestore 恢复
# 全量恢复
docker cp /data/mongo/backup/full_20260727.gz mongo1:/data/restore/
docker exec mongo1 mongorestore \
-u root -p YourStrongPassword123 \
--authenticationDatabase admin \
--oplogReplay \
--gzip \
--archive=/data/restore/full_20260727.gz
# 恢复单库(不覆盖已有数据用 --drop 先删后导)
docker exec mongo1 mongorestore \
-u root -p YourStrongPassword123 \
--authenticationDatabase admin \
-d mydb --drop \
--gzip \
/data/restore/mydb_20260727/mydb
5.4 文件系统快照备份(大库推荐)
# 前提: 数据目录在 LVM 卷上
# 1. 在 Primary 上加锁(不中断读写,只刷盘)
docker exec mongo1 mongosh -u root -p YourStrongPassword123 --eval '
db.fsyncLock()
'
# 2. 创建 LVM 快照
lvcreate -L 10G -s -n mongo_snap /dev/vg0/mongo_data
# 3. 解锁
docker exec mongo1 mongosh -u root -p YourStrongPassword123 --eval '
db.fsyncUnlock()
'
# 4. 挂载快照并备份
mount /dev/vg0/mongo_snap /mnt/snap
tar -czf /backup/mongo_$(date +%Y%m%d).tar.gz -C /mnt/snap .
umount /mnt/snap
lvremove -f /dev/vg0/mongo_snap
云服务器可用云盘快照替代 LVM,更简单。先
fsyncLock,再打快照,再fsyncUnlock。
5.5 定时备份脚本
#!/bin/bash
# /data/mongo/scripts/backup.sh
BACKUP_DIR="/data/mongo/backup"
DATE=$(date +%Y%m%d_%H%M%S)
KEEP_DAYS=7
SECONDARY="mongo2"
mkdir -p ${BACKUP_DIR}
echo "[$(date)] 开始备份..."
docker exec ${SECONDARY} mongodump \
-u root -p YourStrongPassword123 \
--authenticationDatabase admin \
--oplog --gzip \
--archive=/data/backup/full_${DATE}.gz
docker cp ${SECONDARY}:/data/backup/full_${DATE}.gz ${BACKUP_DIR}/
docker exec ${SECONDARY} rm /data/backup/full_${DATE}.gz
# 清理过期备份
find ${BACKUP_DIR} -name "full_*.gz" -mtime +${KEEP_DAYS} -delete
echo "[$(date)] 备份完成: ${BACKUP_DIR}/full_${DATE}.gz"
echo "[$(date)] 已清理 ${KEEP_DAYS} 天前备份"
# crontab 每天凌晨 2 点备份
crontab -e
# 0 2 * * * /data/mongo/scripts/backup.sh >> /data/mongo/logs/backup.log 2>&1
5.6 oplog 增量恢复(Point-in-Time Recovery)
# 场景: 误删数据,需要恢复到误操作前的时间点
# 1. 用全量备份恢复到一个新实例(隔离环境)
# 2. 查看误操作时间
docker exec mongo1 mongosh -u root -p YourStrongPassword123 --eval '
use local
db.oplog.rs.find({
ns: "mydb.users",
op: "d"
}).sort({ ts: -1 }).limit(5)
'
# 3. 用 mongorestore --oplogReplay --oplogLimit 恢复到指定时间点前
# oplogLimit 格式: timestamp:inc
mongorestore \
--host new-mongo \
--oplogReplay \
--oplogLimit 1719000000:1 \
--gzip --archive=full_20260726.gz
6. 安全加固
6.1 认证与授权
// 1. 启动必须带 --auth(已在 docker-compose 配置)
// 2. 最小权限原则: 业务用 readWrite,不用 root
use mydb
db.createUser({
user: "appuser",
pwd: passwordPrompt(), // 交互式输入密码,不留在历史
roles: [{ role: "readWrite", db: "mydb" }]
})
// 3. 只读用户(报表/分析)
db.createUser({
user: "reporter",
pwd: passwordPrompt(),
roles: [{ role: "read", db: "mydb" }]
})
// 4. 查看所有用户
use admin
db.getUsers()
// 5. 定期审计用户权限
db.getUsers().forEach(u => {
print(u.user + ": " + JSON.stringify(u.roles))
})
6.2 内置角色权限矩阵
| 角色 | 读 | 写 | 建索引 | 管用户 | 管库 |
|---|---|---|---|---|---|
| read | Y | - | - | - | - |
| readWrite | Y | Y | - | - | - |
| dbAdmin | Y | Y | Y | - | Y |
| userAdmin | - | - | - | Y | - |
| dbOwner | Y | Y | Y | Y | Y |
| root | Y | Y | Y | Y | Y(所有库) |
6.3 网络安全
# mongod.conf 限制绑定 IP
net:
bindIp: 127.0.0.1,10.0.0.5 # 只绑定内网,不绑 0.0.0.0
port: 27017
# 或 docker-compose
command: ["--bind_ip", "127.0.0.1,172.18.0.1"]
# 防火墙只允许应用服务器 IP
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="10.0.0.10" port port=27017 protocol=tcp accept'
firewall-cmd --reload
# 禁止公网暴露 27017(MongoDB 被勒索病毒扫描的重灾区)
6.4 TLS/SSL 加密传输
# 生成证书(或用企业 CA)
openssl req -newkey rsa:2048 -nodes -keyout mongodb.key -x509 -days 365 -out mongodb.crt
cat mongodb.key mongodb.crt > mongodb.pem
# docker-compose 启用 TLS
command:
- "--tlsMode=requireTLS"
- "--tlsCertificateKeyFile=/data/config/mongodb.pem"
volumes:
- /data/mongo/certs:/data/config
6.5 审计日志(企业版功能,社区版替代方案)
// 社区版可用 profile 记录操作
db.setProfilingLevel(2) // 记录所有操作(性能影响大,仅排查时用)
// 或用 mongod 启动参数开启审计(企业版)
auditLog:
destination: file
format: JSON
path: /var/log/mongodb/audit.log
6.6 安全检查清单
- [ ] 启动参数带
--auth - [ ] root 密码为强密码(16 位+,含大小写数字符号)
- [ ] 业务用户最小权限(readWrite,非 root)
- [ ]
bindIp不含 0.0.0.0(生产) - [ ] 防火墙限制来源 IP
- [ ] 27017 端口不对公网开放
- [ ] 开启 TLS 加密传输
- [ ] 定期轮换密码
- [ ] 禁用未使用的用户
- [ ] 数据文件目录权限 600
7. 日志管理
7.1 日志位置与查看
# Docker 部署日志在容器内 /var/log/mongodb/mongod.log
docker exec mongo1 cat /var/log/mongodb/mongod.log
# 或通过 docker logs
docker logs --tail 100 mongo1
# 实时跟踪
docker logs -f mongo1
# 查找错误
docker logs mongo1 2>&1 | grep -i "error\|fatal\|warning"
7.2 日志级别调整
// 查看当前日志级别
db.getLogComponents()
// 临时提高某组件日志级别(1-5,越高越详细)
db.setLogLevel(2, "command") // 命令日志
db.setLogLevel(2, "query") // 查询日志
db.setLogLevel(1, "replication") // 复制日志
// 排查完恢复
db.setLogLevel(0, "command")
7.3 日志轮转
// MongoDB 内置日志轮转
db.adminCommand({ logRotate: 1 })
// 或配置启动参数定期轮转
// systemLog.logRotate: reopen
// + logrotate 配置
# /etc/logrotate.d/mongodb
/var/log/mongodb/*.log {
daily
rotate 14
compress
delaycompress
missingok
notifempty
copytruncate
}
7.4 关键日志关键词
| 关键词 | 含义 | 处理 |
|---|---|---|
WT_CACHE_EVICT |
缓存驱逐 | 内存不足,调大缓存 |
Replication lag |
复制延迟 | 排查 Secondary 负载 |
Connection refused |
连接拒绝 | 检查 ulimit / maxConn |
Out of memory |
OOM | 容器内存限制太小 |
E11000 duplicate key |
唯一键冲突 | 应用层逻辑问题 |
election |
发起选举 | Primary 切换,检查原因 |
Index build |
建索引中 | 可能影响性能,关注完成 |
8. 副本集运维操作
8.1 添加新节点
// 1. 新节点已用 --replSet rs0 启动且数据目录为空
// 2. 在 Primary 上执行
rs.add({ host: "mongo4:27017", priority: 1 })
// 查看同步进度
rs.status()
// 新节点 stateStr 会从 STARTUP → STARTUP2 → SECONDARY
8.2 移除节点
// 先降级 priority 避免选举抖动
cfg = rs.conf()
cfg.members[3].priority = 0
cfg.members[3].votes = 0
rs.reconfig(cfg)
// 等待稳定后移除
rs.remove("mongo4:27017")
8.3 手动切换 Primary(计划内维护)
// 方法1: stepDown(推荐,平滑切换)
// Primary 主动让位,60 秒内不重新竞选
rs.stepDown(60)
// 方法2: 调整 priority
cfg = rs.conf()
cfg.members[0].priority = 0 // 当前 Primary
cfg.members[1].priority = 2 // 目标节点
rs.reconfig(cfg)
// 切换后恢复 priority
cfg.members[0].priority = 2
cfg.members[1].priority = 1
rs.reconfig(cfg)
8.4 节点重新同步(数据不一致时)
// 1. 在有问题的 Secondary 上停止同步
// 进入该节点容器
docker exec -it mongo2 mongosh -u root -p YourStrongPassword123
// 2. 将节点改为 RECOVERING 状态
db.adminCommand({ replSetMaintenance: true })
// 3. 停止该节点
docker stop mongo2
// 4. 清空数据目录(宿主机)
rm -rf /data/mongo/node2/db/*
// 5. 重新启动
docker start mongo2
// 6. 节点会自动全量同步
rs.status() // 观察 stateStr 变为 SECONDARY
8.5 调整 oplog 大小
// 查看当前 oplog 大小
use local
db.oplog.rs.stats().maxSize
// 调整(只增不减,需在 Primary 执行)
db.adminCommand({
replSetResizeOplog: 1,
size: 51200 // 单位 MB,这里设 50GB
})
oplog 大小建议:至少能容纳 24-48 小时的写入。可通过
rs.printReplicationInfo()查看 oplog 窗口时长。
8.6 修改副本集配置
// 查看当前配置
rs.conf()
// 修改投票节点数 / 优先级 / 隐藏节点
cfg = rs.conf()
cfg.members[2].hidden = true // 设为隐藏节点(不接读请求)
cfg.members[2].priority = 0 // 隐藏节点 priority 必须 0
cfg.members[2].votes = 1
rs.reconfig(cfg)
9. 容量规划
9.1 数据大小估算
// 数据库大小
db.stats()
// 集合大小(含索引)
db.users.stats()
// 只看数据大小(不含索引)
db.users.dataSize() // 原始数据大小
db.users.storageSize() // 磁盘实际占用(压缩后)
db.users.totalIndexSize() // 索引大小
// WiredTiger 压缩比通常 2-4 倍
// storageSize ≈ dataSize / 3
9.2 容量计算公式
磁盘需求 = 数据原始大小 / 压缩比(3) × 副本数(3) + 索引大小 × 副本数(3) + oplog(50GB) + 预留(20%)
示例:100GB 原始数据
- 压缩后数据:100/3 ≈ 33GB
- 索引约数据 10%:3.3GB
- 单节点:33 + 3.3 ≈ 36GB
- 3 副本:108GB
- oplog:50GB(每节点)
- 总计:(36 + 50) × 3 ≈ 258GB
- 加 20% 预留:约 310GB
9.3 内存规划
- WiredTiger 缓存:物理内存 × 60%
- 工作集(热数据)应能放入缓存
- 经验:如果
bytes currently in cache接近max bytes configured,说明内存吃紧
9.4 连接数规划
最大连接数 = (可用内存 MB / 单连接内存) × 安全系数
单连接约占 1-2MB
8GB 内存 → maxConn ≈ 8000 × 0.5 = 4000(保守)
9.5 何时扩容信号
- 缓存命中率持续 < 95%
- 磁盘使用率 > 70%
- 复制延迟频繁超 10 秒
- 慢查询数量上升
- 连接数接近上限
10. 版本升级与回滚
10.1 升级原则
- 副本集滚动升级:逐个节点升级,保持多数派在线
- 只能升级相邻大版本:5.0 → 6.0 → 7.0,不能跳级
- 先升 Secondary,最后升 Primary
- 升级前必须备份
10.2 副本集滚动升级步骤
# 假设从 6.0 升级到 7.0
# 0. 全量备份(第 5 节)
# 1. 设置兼容版本(在 Primary 执行)
docker exec mongo1 mongosh -u root -p YourStrongPassword123 --eval '
db.adminCommand({ setFeatureCompatibilityVersion: "6.0" })
'
# 2. 升级第一个 Secondary (mongo2)
docker stop mongo2
docker rm mongo2
# 修改 docker-compose 镜像版本为 mongo:7.0
docker compose up -d mongo2
# 等待 mongo2 恢复为 SECONDARY
docker exec mongo1 mongosh -u root -p YourStrongPassword123 --eval 'rs.status()'
# 3. 升级第二个 Secondary (mongo3)
docker stop mongo3 && docker rm mongo3
docker compose up -d mongo3
# 等待恢复 SECONDARY
# 4. 手动切换 Primary 到已升级节点
docker exec mongo1 mongosh -u root -p YourStrongPassword123 --eval 'rs.stepDown(60)'
# 5. 升级原 Primary (mongo1)
docker stop mongo1 && docker rm mongo1
docker compose up -d mongo1
# 等待恢复
# 6. 升级 featureCompatibilityVersion(全部升级后)
docker exec mongo1 mongosh -u root -p YourStrongPassword123 --eval '
db.adminCommand({ setFeatureCompatibilityVersion: "7.0" })
'
# 7. 验证
docker exec mongo1 mongosh -u root -p YourStrongPassword123 --eval 'rs.status()'
10.3 回滚
# 回滚只能回到升级前的版本,且需在 setFeatureCompatibilityVersion 之前
# 一旦执行了 setFeatureCompatibilityVersion "7.0",无法降级数据格式
# 回滚步骤:
# 1. 停止 7.0 节点
# 2. 用备份恢复数据
# 3. 启动 6.0 版本
关键:
setFeatureCompatibilityVersion是不可逆操作!升级后观察一段时间再执行。
11. 故障排查手册
11.1 故障一:响应变慢
// Step 1: 看活跃操作
db.currentOp({ active: true, secs_running: { $gte: 1 } })
// Step 2: 杀掉慢操作
db.killOp("shard:12345")
// Step 3: 分析慢查询
db.system.profile.find().sort({ millis: -1 }).limit(5)
// Step 4: 查执行计划
db.coll.find({...}).explain("executionStats")
// 看 stage 是否 COLLSCAN(全表扫描)
// Step 5: 查锁等待
db.serverStatus().globalLock.currentQueue
// readers/writers > 0 说明有锁排队
// Step 6: 查内存
db.serverStatus().wiredTiger.cache
// "pages evicted" 高 = 内存不足
// Step 7: 查连接
db.serverStatus().connections
// current 接近 available 上限 = 连接耗尽
11.2 故障二:连接被拒
# Step 1: mongod 是否存活
docker ps | grep mongo
docker logs --tail 50 mongo1
# Step 2: 端口是否监听
netstat -tlnp | grep 27017
# Step 3: 系统连接限制
ulimit -n
cat /proc/$(pidof mongod)/limits | grep "open files"
# Step 4: MongoDB 连接上限
docker exec mongo1 mongosh -u root -p YourStrongPassword123 --eval '
db.serverStatus().connections
'
# Step 5: 网络/防火墙
firewall-cmd --list-ports
telnet <host> 27017
# Step 6: 认证
# 检查连接串 authSource 是否正确
# mongodb://user:pass@host/db?authSource=admin
11.3 故障三:复制延迟
// Step 1: 查看各节点状态
rs.status()
// 找出 stateStr 非 SECONDARY 或 lag 大的节点
// Step 2: 查看复制延迟详情
rs.printSecondaryReplicationInfo()
// Step 3: 查看延迟节点日志
// docker logs mongo2 | grep -i "replication\|error"
// Step 4: 查 Secondary 负载
// 是否 Secondary 承担了大量读请求或建索引
db.currentOp(true)
// Step 5: 查网络
ping -c 10 mongo2
// Step 6: 严重延迟时重新同步(见 8.4)
11.4 故障四:Primary 频繁切换
// Step 1: 查看选举历史
rs.status()
// Step 2: 查日志
// docker logs mongo1 | grep -i "election"
// 常见原因:
// - Primary 资源不足(OOM、CPU 满载)
// - 网络抖动(心跳超时)
// - 磁盘 IO 满载导致心跳响应慢
// - priority 配置不合理
// Step 3: 排查资源
docker stats mongo1
iostat -x 1
free -m
11.5 故障五:磁盘满
# Step 1: 确认磁盘
df -h
# Step 2: 找大文件
du -sh /data/mongo/node1/* | sort -rh
# Step 3: 紧急处理
# - 清理旧日志
docker exec mongo1 rm /var/log/mongodb/mongod.log.*
# - 清理 profile
docker exec mongo1 mongosh -u root -p YourStrongPassword123 --eval '
db.setProfilingLevel(0)
db.system.profile.drop()
'
# - 压缩数据(compact,需停写)
docker exec mongo1 mongosh -u root -p YourStrongPassword123 --eval '
db.runCommand({ compact: "users" })
'
# Step 4: 长期方案:扩容磁盘 / 分片
11.6 故障六:数据损坏
# 症状: 启动报错 "WiredTiger error"
# Step 1: 停止 mongod
docker stop mongo1
# Step 2: 尝试修复(不一定成功)
docker run --rm -v /data/mongo/node1/db:/data/db mongo:7.0 \
mongod --repair --dbpath /data/db
# Step 3: 修复失败则从备份恢复(第 5 节)
# 或从副本集其他节点重新同步(8.4)
12. 应急预案
12.1 Primary 宕机
影响: 写入中断 10-30 秒,自动选举新 Primary
处理:
1. 不用手动干预,等待自动选举(通常 < 30s)
2. 检查应用是否自动重连(连接串需含多个节点)
3. 排查宕机原因(OOM / 磁盘满 / 进程崩溃)
4. 修复原 Primary 后重启,会自动作为 Secondary 重新加入
12.2 多数派节点故障(脑裂/不可写)
影响: 副本集无法选举,完全不可写
处理:
1. 紧急启用单节点模式(仅灾难恢复用):
docker exec mongo1 mongosh -u root -p YourStrongPassword123 --eval '
db.adminCommand({ replSetForceResync: 1 })
'
# 或强制重配置为单节点
cfg = { _id: "rs0", members: [{ _id: 0, host: "mongo1:27017" }] }
db.adminCommand({ replSetReconfig: cfg, force: true })
2. 立即从备份恢复数据到新集群
3. 此操作有数据丢失风险,仅最后手段
12.3 误删数据
处理:
1. 立即停止应用写入(防止覆盖)
2. 从最近的备份恢复到新实例
3. 用 oplog 重放到误删前时间点(5.6 节)
4. 导出误删数据,写回生产库
12.4 安全事件(被勒索/未授权访问)
处理:
1. 立即断网(防火墙封禁 27017 对外)
2. 检查是否开启 auth(未开则数据已泄露)
3. 备份当前数据(留证)
4. 修改所有密码
5. 开启 auth + 绑定内网 IP
6. 评估泄露范围,按合规要求上报
13. 日常巡检清单
每日检查
# 1. 副本集状态
docker exec mongo1 mongosh -u root -p YourStrongPassword123 --eval 'rs.status()' | grep stateStr
# 2. 复制延迟
docker exec mongo1 mongosh -u root -p YourStrongPassword123 --eval 'rs.printSecondaryReplicationInfo()'
# 3. 磁盘空间
df -h | grep mongo
# 4. 容器状态
docker ps | grep mongo
# 5. 备份是否成功
ls -lh /data/mongo/backup/ | tail -5
# 6. 错误日志
docker logs --since 24h mongo1 2>&1 | grep -i "error\|fatal" | head -20
每周检查
// 1. 连接数趋势
db.serverStatus().connections
// 2. 缓存命中率
db.serverStatus().wiredTiger.cache
// 计算: (bytes read into cache) / (bytes read into cache + pages requested from cache)
// 3. 慢查询 TOP 10
db.system.profile.find().sort({ millis: -1 }).limit(10)
// 4. 索引使用情况
db.users.aggregate([{ $indexStats: {} }])
// 5. 数据增长
db.stats()
每月检查
# 1. 数据大小趋势
docker exec mongo1 mongosh -u root -p YourStrongPassword123 --eval 'db.stats()' >> /data/mongo/logs/stats_$(date +%Y%m).log
# 2. 用户权限审计
docker exec mongo1 mongosh -u root -p YourStrongPassword123 --eval '
use admin
db.getUsers()
'
# 3. oplog 窗口是否足够
docker exec mongo1 mongosh -u root -p YourStrongPassword123 --eval 'rs.printReplicationInfo()'
# 4. 测试备份恢复(在测试环境)
# 5. 系统资源趋势分析(CPU/内存/IO 月度报告)
巡检脚本(可加入 crontab 每日执行)
#!/bin/bash
# /data/mongo/scripts/daily_check.sh
DATE=$(date +%Y%m%d_%H%M%S)
LOG="/data/mongo/logs/daily_check_${DATE}.log"
HOST="mongo1"
PASS="YourStrongPassword123"
mkdir -p /data/mongo/logs
echo "===== MongoDB 日常巡检 $DATE =====" > $LOG
echo -e "\n[1] 容器状态" >> $LOG
docker ps | grep mongo >> $LOG
echo -e "\n[2] 副本集状态" >> $LOG
docker exec $HOST mongosh -u root -p $PASS --quiet --eval '
rs.status().members.forEach(m => {
print(m.name + " | " + m.stateStr + " | lag: " + (m.optimeDate ? m.optimeDate : "N/A"))
})
' >> $LOG
echo -e "\n[3] 连接数" >> $LOG
docker exec $HOST mongosh -u root -p $PASS --quiet --eval '
let c = db.serverStatus().connections
print("current: " + c.current + " / available: " + c.available)
' >> $LOG
echo -e "\n[4] 磁盘空间" >> $LOG
df -h | grep -E "mongo|Filesystem" >> $LOG
echo -e "\n[5] 最近错误日志" >> $LOG
docker logs --since 24h $HOST 2>&1 | grep -i "error\|fatal\|warning" | tail -10 >> $LOG
echo -e "\n[6] 备份文件" >> $LOG
ls -lh /data/mongo/backup/ | tail -3 >> $LOG
echo "巡检完成: $LOG"
附录:常用运维命令速查
// == 副本集 ==
rs.status() // 副本集状态
rs.isMaster() // 当前节点角色
rs.conf() // 副本集配置
rs.add("host:27017") // 添加节点
rs.remove("host:27017") // 移除节点
rs.stepDown(60) // Primary 让位
rs.printReplicationInfo() // oplog 信息
rs.printSecondaryReplicationInfo() // 各节点延迟
// == 服务器状态 ==
db.serverStatus() // 完整状态
db.serverStatus().connections // 连接数
db.serverStatus().opcounters // 操作计数
db.serverStatus().wiredTiger.cache // 缓存
db.serverStatus().mem // 内存
// == 操作与性能 ==
db.currentOp({active:true}) // 当前操作
db.killOp("opid") // 杀操作
db.setProfilingLevel(1,{slowms:100}) // 开慢查询
db.system.profile.find() // 慢查询记录
// == 数据大小 ==
db.stats() // 库统计
db.coll.stats() // 集合统计
db.coll.dataSize() // 数据大小
db.coll.storageSize() // 磁盘占用
db.coll.totalIndexSize() // 索引大小
// == 索引 ==
db.coll.getIndexes() // 查看索引
db.coll.createIndex({field:1}) // 建索引
db.coll.dropIndex("name") // 删索引
db.coll.aggregate([{$indexStats:{}}]) // 索引使用统计
// == 用户 ==
use admin
db.getUsers() // 所有用户
db.createUser({...}) // 建用户
db.dropUser("name") // 删用户
db.changeUserPassword("user","new")// 改密码
// == 维护 ==
db.fsyncLock() // 加锁(快照备份前)
db.fsyncUnlock() // 解锁
db.runCommand({compact:"coll"}) // 压缩集合
db.runCommand({repairDatabase:1}) // 修复(慎用)
运维学习路线
- 入门: 单机部署 → 熟悉 mongosh → 掌握 serverStatus 等诊断命令
- 副本集: 搭建 3 节点副本集 → 理解选举机制 → 练习故障转移
- 监控: 部署 Prometheus + Grafana → 理解五大监控维度 → 配置告警
- 备份: 实践 mongodump / 文件快照 → 演练恢复流程 → 搭建定时备份
- 调优: 理解 WiredTiger → 实践索引优化 → 慢查询治理
- 进阶: 分片集群 → 容量规划 → 版本升级演练
- 应急: 制定应急预案 → 定期故障演练 → 复盘总结
官方运维文档: https://www.mongodb.com/docs/manual/administration/
生产部署建议: https://www.mongodb.com/docs/manual/administration/production-notes/
```