# 配置

# 配置文件

  • 旧版 MongoDB 的配置文件采用 ini 格式,从 2.6 版开始推荐采用 YAML 格式,分为 storage、systemLog、net 等多个大类。

# 示例

net:
  port: 27017
  bindIp: 0.0.0.0
  # bindIp: localhost,10.0.0.1,/tmp/mongod.sock   # 可以绑定多个 IP 供客户端访问

# processManagement:
#   fork: false               # 是否作为 daemon 进程运行
#   pidFilePath: /var/run/mongod.pid

security:
  authorization: enabled      # 是否对客户端启用 RBAC 认证,默认为 disabled
  # clusterAuthMode: keyFile  # 集群各节点之间的认证方式

storage:
  dbPath: /var/lib/mongo      # 存储数据的目录
  # indexBuildRetry: true     # 如果 mongod 在构建索引的过程中退出,当 mongod 重启时,是否删除不完整的索引,尝试重建它们
  # journal:
  #   enabled: true           # 是否启用 WiredTiger 预写日志,默认为 true
  # engine: wiredTiger        # 采用的存储引擎
  # wiredTiger:               # wiredTiger 存储引擎的配置
  #   engineConfig:
  #      cacheSizeGB: 2       # 内部缓存的最大体积,单位为 GB 。默认为 (RAM-1GB)*50% ,至少为 0.25GB

systemLog:                    # 服务器日志
  # verbosity: 0              # 日志级别,取值范围为 0 ~ 5 ,对应 INFO ~ DEBUG
  destination: file           # 日志的输出方向,可以为 file 或 syslog 。默认输出到 stdout
  path: /var/log/mongo/mongod.log
  logAppend: true             # mongo 重启后,是否将日志以追加方式写到之前的日志文件。默认为 false ,会备份之前你的日志文件,并创建新的日志文件

operationProfiling:           # 慢查询日志
  mode: slowOp                # 工作模式,默认为 off
  # slowOpThresholdMs: 100
  # slowOpSampleRate: 1       # 慢查询的采样率,取值范围为 0~1 。对于副本集的从节点,采样率总是 1
  • 慢查询日志的几种模式:
    off       # 不记录
    all       # 记录所有数据库操作
    slowOp    # 只记录执行时长超过 slowOpThresholdMs 阈值的操作
    
    • 慢查询日志会记录到当前 DB 的 system.profile 集合里,该集合的最大容量为 1MB 。

# 存储引擎

  • In-Memory
    • 存储在内存中。
    • 该引擎仅企业版可用。
  • MMAPv1
    • MongoDB v3.2 之前的默认引擎。
  • WiredTiger
    • MongoDB v3.2 开始的默认引擎。
    • 支持多个客户端同时修改同一集合的不同文档。
    • 每隔一定时间,WiredTiger 会将内存中所有数据写入磁盘,建立一次快照,称为检查点(checkpoint)。
      • 在两个检查点之间,WiredTiger 采用预写日志来临时记录数据库的所有写操作,相当于增量备份。
      • 如果 mongod 非正常退出,重启时会自动回滚到上一个检查点,并使用预写日志来恢复数据。
      • 每写入一个新的检查点之后,就会删除之前的检查点、预写日志。
    • 删除文档时并不会实际释放磁盘空间,而是留着供当前集合写入新文档。除非直接删除集合。
      • 查看存储信息:
        db.<collection>.stats().size        // 集合的数据量,即读取到内存之后的体积,单位 bytes
        db.<collection>.stats().storageSize // 占用的磁盘空间。可能比 size 小,因为默认进行压缩。也可能比 size 大,因为删除的文档不会释放磁盘空间
        db.stats().dataSize                 // 数据库的数据量
        db.stats().storageSize              // 占用的磁盘空间
        
      • 为了清理磁盘空间,可以将原集合 copy 到一个新集合,然后将原集合 drop ,最后将新集合 rename 为原集合。
      • 可以执行 db.runCommand({compact:'<collection>'}) ,整理一个集合,释放不需要的磁盘空间。
        • 它的原理也是将集合的数据拷贝一份,重新写入磁盘,因此需要一定冗余空间。
        • 从 Mongo v4.4 开始,该命令不会阻塞集合的 CRUD 操作。
        • 在副本集中,Secondary 节点并不会同步该命令,需要到每个节点执行该命令。

# 访问控制

# 身份认证

  • MongoDB 默认没有启用身份认证,可按以下步骤启用:
    1. 进入 MongoDB 终端,创建一个管理员用户:
      use admin
      db.createUser(
        {
          user: 'root',
          pwd: '******',
          roles: [{role: 'root', db: 'admin'}]
        }
      )
      
    2. 退出 MongoDB 终端,执行 mongod --auth 重启 MongoDB 服务器,启用身份认证。
  • 如果已启用身份认证,但是不知道管理员账号,则可以先用 mongod ---noauth 重启服务器,再创建管理员账号。
  • 如果已启用身份认证,则启动客户端时,需要传入用户名、密码,并指定用于验证该用户的数据库。例如 mongo mongodb://127.0.0.1:27017?authSource=admin -u root -p ******
    • 默认采用当前连接的数据库作为验证数据库,检查该用户在该数据库中是否有效。如果不存在该用户名,或密码错误,则报错:Authentication failed
    • 可以先启动客户端,再进行密码认证:
      mongo 127.0.0.1:27017/admin
      db.auth('root', '******')
      

# 管理用户

  • MongoDB 支持启用基于角色的访问控制(RBAC)。
    • 在 admin 数据库的 system.users 集合中存储了所有用户的信息,包括用户名、密钥、所属数据库、分配的角色。
    • 每个用户登录时,除了输入密码,还需要指定所属的数据库进行身份认证。
  • 普通数据库定义了以下角色:
    • read :可以读取数据库
    • readWrite :可以读写数据库
    • dbAdmin :可以管理数据库
    • userAdmin :可以管理用户
  • admin 数据库定义了以下角色:
    • readAnyDatabase
    • readWriteAnyDatabase
    • dbAdminAnyDatabase
    • userAdminAnyDatabase
    • clusterAdmin :可以管理副本集
    • root :超级管理员,拥有所有权限
      • root 用户登录时依然只能指定 admin 数据库进行验证。
  • 例:
    // 显示当前数据库的所有用户
    show users
    // 创建一个用户
    db.createUser({user: 'user1', pwd: '******', roles: [{role: 'readWrite', db: 'db1'}]})
    // 删除用户
    db.dropUser('user1')
    // 给用户分配权限
    db.grantRolesToUser('user1', [{role: 'readWrite', db: 'db1'}, [{role: 'read', db: 'db2'}])
    // 删除用户的权限
    db.revokeRolesFromUser('user1', [{role: 'readWrite', db: 'db1'}])