mcpField
M
mongodb

mongodb

github.com/bagelhole数据与数据库1.2k342 次安装23 周前更新
代码仓库

关于 mongodb

面向开发和生产环境的 MongoDB 管理技能,涵盖部署、安全、性能优化与故障排查。适合负责文档型数据库运维的工程师。

主要功能

  1. 01安装与初始配置
  2. 02用户认证与安全设置
  3. 03索引和聚合优化
  4. 04副本集配置
  5. 05备份、恢复与监控
  6. 06常见问题排查

适用场景

  1. 01部署 MongoDB 数据库
  2. 02为应用配置用户和认证
  3. 03优化查询与聚合性能
  4. 04备份数据库并检查运行状态

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/bagelhole/devops-security-agent-skills --skill mongodb

安装后在 Claude Code 中输入/mongodb确认已加载。

详细介绍

MongoDB

在开发和生产环境中管理、优化并保护 MongoDB NoSQL 数据库。

适用场景

  • 你需要使用灵活架构的面向文档数据库。
  • 你的数据是半结构化的,或包含大量嵌套内容(类似 JSON 的文档)。
  • 你需要通过分片实现水平扩展。
  • 你的应用可以受益于丰富的查询功能和聚合管道。

先决条件

  • Linux 服务(Debian/Ubuntu 或基于 RHEL 的系统)或 Docker。
  • 安装软件包所需的 Root 或 sudo 访问权限。
  • 生产环境建议使用 MongoDB 7.x(仍支持 6.x)。

安装和设置

# Debian / Ubuntu — MongoDB 7
curl -fsSL https://www.mongodb.org/static/pgp/server-7.0.asc | \
  sudo gpg -o /usr/share/keyrings/mongodb-server-7.0.gpg --dearmor
echo "deb [ signed-by=/usr/share/keyrings/mongodb-server-7.0.gpg ] \
  https://repo.mongodb.org/apt/ubuntu jammy/mongodb-org/7.0 multiverse" | \
  sudo tee /etc/apt/sources.list.d/mongodb-org-7.0.list
sudo apt update
sudo apt install -y mongodb-org

# Start and enable
sudo systemctl enable --now mongod

# Verify
mongosh --eval "db.version()"

初始用户设置

// Connect without auth first
// mongosh

use admin

// Create admin user
db.createUser({
  user: "admin",
  pwd: "strong_admin_password",
  roles: [
    { role: "userAdminAnyDatabase", db: "admin" },
    { role: "readWriteAnyDatabase", db: "admin" },
    { role: "clusterAdmin", db: "admin" }
  ]
})

// Create an application-scoped user
use mydb
db.createUser({
  user: "myapp",
  pwd: "strong_app_password",
  roles: [{ role: "readWrite", db: "mydb" }]
})

在 /etc/mongod.conf 中启用身份验证:

security:
  authorization: enabled
sudo systemctl restart mongod
# Now connect with credentials
mongosh -u myapp -p strong_app_password --authenticationDatabase mydb

mongosh 命令参考

// Show databases and collections
show dbs
use mydb
show collections

// Insert documents
db.users.insertOne({ name: "Alice", email: "[email protected]", age: 30 })
db.users.insertMany([
  { name: "Bob", email: "[email protected]", age: 25 },
  { name: "Carol", email: "[email protected]", age: 35 }
])

// Query documents
db.users.find({ age: { $gte: 25 } }).sort({ name: 1 }).limit(10)
db.users.findOne({ email: "[email protected]" })
db.users.countDocuments({ age: { $gte: 30 } })

// Update
db.users.updateOne(
  { email: "[email protected]" },
  { $set: { age: 31 }, $currentDate: { updatedAt: true } }
)
db.users.updateMany(
  { age: { $lt: 30 } },
  { $set: { tier: "junior" } }
)

// Delete
db.users.deleteOne({ email: "[email protected]" })
db.users.deleteMany({ tier: "junior" })

索引

// Single-field index
db.users.createIndex({ email: 1 }, { unique: true })

// Compound index
db.orders.createIndex({ userId: 1, createdAt: -1 })

// Text index for search
db.articles.createIndex({ title: "text", body: "text" })
db.articles.find({ $text: { $search: "mongodb scaling" } })

// TTL index — auto-delete documents after 30 days
db.sessions.createIndex({ createdAt: 1 }, { expireAfterSeconds: 2592000 })

// List indexes
db.users.getIndexes()

// Drop an index
db.users.dropIndex("email_1")

// Explain a query to verify index usage
db.orders.find({ userId: 42 }).explain("executionStats")

聚合管道示例

// Revenue per status
db.orders.aggregate([
  { $group: {
      _id: "$status",
      totalRevenue: { $sum: "$total" },
      count: { $sum: 1 }
  }},
  { $sort: { totalRevenue: -1 } }
])

// Top 5 customers by order value (with a join)
db.orders.aggregate([
  { $group: {
      _id: "$userId",
      spent: { $sum: "$total" },
      orderCount: { $sum: 1 }
  }},
  { $sort: { spent: -1 } },
  { $limit: 5 },
  { $lookup: {
      from: "users",
      localField: "_id",
      foreignField: "_id",
      as: "user"
  }},
  { $unwind: "$user" },
  { $project: {
      _id: 0,
      name: "$user.name",
      email: "$user.email",
      spent: 1,
      orderCount: 1
  }}
])

// Daily signup trend
db.users.aggregate([
  { $group: {
      _id: { $dateToString: { format: "%Y-%m-%d", date: "$createdAt" } },
      signups: { $sum: 1 }
  }},
  { $sort: { _id: 1 } },
  { $limit: 30 }
])

副本集设置

副本集至少需要三个成员(或两个数据承载节点加一个仲裁节点)。

每个成员的配置文件
# /etc/mongod.conf (adjust port and dbPath per member)
storage:
  dbPath: /var/lib/mongodb
net:
  port: 27017
  bindIp: 0.0.0.0
replication:
  replSetName: rs0
security:
  authorization: enabled
  keyFile: /etc/mongodb-keyfile
# Generate a shared keyfile for internal auth
openssl rand -base64 756 > /etc/mongodb-keyfile
chmod 400 /etc/mongodb-keyfile
chown mongodb:mongodb /etc/mongodb-keyfile
# Copy this file to all replica set members
初始化副本集
// Connect to the first member
// mongosh --port 27017

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 }
  ]
})

// Check status
rs.status()

// View replication lag per member
rs.printReplicationInfo()
rs.printSecondaryReplicationInfo()

备份和恢复

# Full dump of all databases
mongodump --uri="mongodb://admin:secret@localhost:27017" --out=/backups/full_$(date +%F)

# Single database
mongodump --uri="mongodb://myapp:secret@localhost:27017/mydb" --out=/backups/mydb_$(date +%F)

# Compressed dump
mongodump --uri="mongodb://admin:secret@localhost:27017" --gzip --out=/backups/gz_$(date +%F)

# Restore all databases
mongorestore --uri="mongodb://admin:secret@localhost:27017" /backups/full_2025-01-15/

# Restore a single database, dropping existing data first
mongorestore --uri="mongodb://admin:secret@localhost:27017" \
  --drop --db mydb /backups/mydb_2025-01-15/mydb/

# Restore compressed dump
mongorestore --uri="mongodb://admin:secret@localhost:27017" --gzip /backups/gz_2025-01-15/

Docker Compose 设置

# docker-compose.yml
version: "3.9"

services:
  mongo1:
    image: mongo:7
    restart: unless-stopped
    ports:
      - "27017:27017"
    environment:
      MONGO_INITDB_ROOT_USERNAME: admin
      MONGO_INITDB_ROOT_PASSWORD: secret
    volumes:
      - mongo1_data:/data/db
      - ./mongo-keyfile:/etc/mongodb-keyfile:ro
    command: >
      mongod
        --replSet rs0
        --keyFile /etc/mongodb-keyfile
        --bind_ip_all
    healthcheck:
      test: ["CMD", "mongosh", "--eval", "db.adminCommand('ping')"]
      interval: 10s
      timeout: 5s
      retries: 5

  mongo2:
    image: mongo:7
    restart: unless-stopped
    volumes:
      - mongo2_data:/data/db
      - ./mongo-keyfile:/etc/mongodb-keyfile:ro
    command: >
      mongod
        --replSet rs0
        --keyFile /etc/mongodb-keyfile
        --bind_ip_all

  mongo3:
    image: mongo:7
    restart: unless-stopped
    volumes:
      - mongo3_data:/data/db
      - ./mongo-keyfile:/etc/mongodb-keyfile:ro
    command: >
      mongod
        --replSet rs0
        --keyFile /etc/mongodb-keyfile
        --bind_ip_all

  mongo-init:
    image: mongo:7
    restart: "no"
    depends_on:
      mongo1:
        condition: service_healthy
    entrypoint: >
      mongosh --host mongo1 -u admin -p secret --authenticationDatabase admin --eval '
        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 }
          ]
        })
      '

volumes:
  mongo1_data:
  mongo2_data:
  mongo3_data:
# Generate keyfile before starting
openssl rand -base64 756 > mongo-keyfile
chmod 400 mongo-keyfile

docker compose up -d

# Connect
mongosh "mongodb://admin:[email protected]:27017/?replicaSet=rs0&authSource=admin"

监控查询

// Server status summary
db.serverStatus().connections
db.serverStatus().opcounters

// Current operations (look for long-running queries)
db.currentOp({ secs_running: { $gte: 5 } })

// Collection stats
db.orders.stats()

// Index sizes
db.orders.stats().indexSizes

// Profiler — log slow queries (> 100ms)
db.setProfilingLevel(1, { slowms: 100 })
db.system.profile.find().sort({ ts: -1 }).limit(5)

// Replica set lag
rs.printSecondaryReplicationInfo()

配置调优

# /etc/mongod.conf — production recommendations
storage:
  dbPath: /var/lib/mongodb
  journal:
    enabled: true
  wiredTiger:
    engineConfig:
      cacheSizeGB: 4          # ~50% of RAM, leave rest for OS cache
    collectionConfig:
      blockCompressor: snappy
net:
  port: 27017
  bindIp: 0.0.0.0
  maxIncomingConnections: 500
operationProfiling:
  mode: slowOp
  slowOpThresholdMs: 100

故障排除

症状可能原因解决方法
explain 输出中出现 COLLSCAN查询字段缺少索引创建合适的索引
副本集成员卡在 RECOVERING 状态超出 oplog 时间窗口删除数据并重启该成员以重新同步
too many open files操作系统文件描述符限制过低在服务文件中设置 ulimit -n 65535
内存使用量过高WiredTiger 缓存过大在配置中减小 cacheSizeGB
聚合管道速度缓慢$match 阶段的字段没有索引添加索引;尽可能将 $match 放在管道前面
身份验证失败authenticationDatabase 错误为管理员用户指定 --authenticationDatabase admin

相关技能

评论

支持 Markdown