Skip to content

MongoDB 复制集管理命令

命令分类

MongoDB 复制集管理命令主要分为以下几类:

  • 配置管理命令:用于查看和修改复制集配置
  • 状态查询命令:用于查看复制集状态和成员信息
  • 成员管理命令:用于添加、移除和修改复制集成员
  • 选举管理命令:用于控制复制集选举
  • 同步管理命令:用于管理复制集成员间的同步

命令执行方式

复制集管理命令主要通过以下方式执行:

  • mongosh shell:在 mongosh 中直接执行
  • 驱动程序 API:通过 MongoDB 驱动程序调用
  • HTTP API:通过 MongoDB 的 HTTP 接口调用(仅适用于某些命令)

命令权限要求

执行复制集管理命令通常需要:

  • 连接到复制集的主节点(某些命令也可以在从节点执行)
  • 具有 clusterManagerclusterAdmin 角色
  • 对于分片集群中的复制集,可能需要额外的权限

配置管理命令

rs.conf()

功能描述

查看当前复制集的配置信息。

语法

javascript
rs.conf()

输出示例

javascript
{
  _id: 'rs0',
  version: 3,
  term: 1,
  members: [
    {
      _id: 0,
      host: 'mongodb0.example.com:27017',
      arbiterOnly: false,
      buildIndexes: true,
      hidden: false,
      priority: 1,
      tags: {},
      secondaryDelaySecs: NumberLong(0),
      votes: 1
    },
    {
      _id: 1,
      host: 'mongodb1.example.com:27017',
      arbiterOnly: false,
      buildIndexes: true,
      hidden: false,
      priority: 1,
      tags: {},
      secondaryDelaySecs: NumberLong(0),
      votes: 1
    },
    {
      _id: 2,
      host: 'mongodb2.example.com:27017',
      arbiterOnly: false,
      buildIndexes: true,
      hidden: false,
      priority: 1,
      tags: {},
      secondaryDelaySecs: NumberLong(0),
      votes: 1
    }
  ],
  protocolVersion: Long(1),
  writeConcernMajorityJournalDefault: true,
  settings: {
    chainingAllowed: true,
    heartbeatIntervalMillis: 2000,
    heartbeatTimeoutSecs: 10,
    electionTimeoutMillis: 10000,
    catchUpTimeoutMillis: -1,
    catchUpTakeoverDelayMillis: 30000,
    getLastErrorModes: {},
    getLastErrorDefaults: {
      w: 1,
      wtimeout: 0
    },
    replicaSetId: ObjectId('5f8d04a0a0b1c2d3e4f5a6b7')
  }
}

使用场景

  • 查看复制集的当前配置
  • 验证复制集配置是否符合预期
  • 准备修改复制集配置前的参考

rs.reconfig()

功能描述

修改复制集的配置。

语法

javascript
rs.reconfig(config, options)

参数说明

  • config:复制集配置文档
  • options:可选参数,包括:
    • force:布尔值,是否强制应用配置(用于处理特殊情况)

示例

javascript
// 获取当前配置
var config = rs.conf();

// 修改成员优先级
config.members[0].priority = 2;

// 应用新配置
rs.reconfig(config);

使用场景

  • 修改复制集成员的优先级
  • 添加或移除复制集成员
  • 修改复制集的选举超时时间
  • 配置复制集成员的标签

注意事项

  • 只能在主节点执行
  • 可能会触发选举
  • 建议先备份当前配置
  • 使用 force 选项时要谨慎,可能导致数据不一致

状态查询命令

rs.status()

功能描述

查看复制集的当前状态。

语法

javascript
rs.status()

输出示例

javascript
{
  set: 'rs0',
  date: ISODate('2023-01-01T00:00:00.000Z'),
  myState: 1,
  term: Long(1),
  syncSourceHost: '',
  syncSourceId: -1,
  heartbeatIntervalMillis: Long(2000),
  majorityVoteCount: 2,
  writeMajorityCount: 2,
  votingMembersCount: 3,
  writableVotingMembersCount: 3,
  optimes: {
    lastCommittedOpTime: {
      ts: Timestamp({ t: 1672531200, i: 1 }),
      t: Long(1)
    },
    lastCommittedWallTime: ISODate('2023-01-01T00:00:00.000Z'),
    readConcernMajorityOpTime: {
      ts: Timestamp({ t: 1672531200, i: 1 }),
      t: Long(1)
    },
    appliedOpTime: {
      ts: Timestamp({ t: 1672531200, i: 1 }),
      t: Long(1)
    },
    durableOpTime: {
      ts: Timestamp({ t: 1672531200, i: 1 }),
      t: Long(1)
    },
    lastAppliedWallTime: ISODate('2023-01-01T00:00:00.000Z'),
    lastDurableWallTime: ISODate('2023-01-01T00:00:00.000Z')
  },
  lastStableRecoveryTimestamp: Timestamp({ t: 1672531200, i: 1 }),
  electionCandidateMetrics: {
    lastElectionReason: 'electionTimeout',
    lastElectionDate: ISODate('2023-01-01T00:00:00.000Z'),
    electionTerm: Long(1),
    lastCommittedOpTimeAtElection: {
      ts: Timestamp({ t: 1672531190, i: 1 }),
      t: Long(0)
    },
    lastSeenOpTimeAtElection: {
      ts: Timestamp({ t: 1672531190, i: 1 }),
      t: Long(0)
    },
    numVotesNeeded: 2,
    priorityAtElection: 1,
    electionTimeoutMillis: Long(10000),
    numCatchUpOps: Long(0),
    newTermStartDate: ISODate('2023-01-01T00:00:00.000Z'),
    wMajorityWriteAvailabilityDate: ISODate('2023-01-01T00:00:00.000Z')
  },
  members: [
    {
      _id: 0,
      name: 'mongodb0.example.com:27017',
      health: 1,
      state: 1,
      stateStr: 'PRIMARY',
      uptime: 3600,
      optime: {
        ts: Timestamp({ t: 1672531200, i: 1 }),
        t: Long(1)
      },
      optimeDate: ISODate('2023-01-01T00:00:00.000Z'),
      lastHeartbeat: ISODate('2023-01-01T00:00:00.000Z'),
      lastHeartbeatRecv: ISODate('2023-01-01T00:00:00.000Z'),
      pingMs: Long(1),
      lastHeartbeatMessage: '',
      syncSourceHost: '',
      syncSourceId: -1,
      infoMessage: '',
      electionTime: Timestamp({ t: 1672531200, i: 1 }),
      electionDate: ISODate('2023-01-01T00:00:00.000Z'),
      configVersion: 3,
      configTerm: 1,
      self: true,
      lastHeartbeatReceived: ISODate('2023-01-01T00:00:00.000Z')
    },
    {
      _id: 1,
      name: 'mongodb1.example.com:27017',
      health: 1,
      state: 2,
      stateStr: 'SECONDARY',
      uptime: 3500,
      optime: {
        ts: Timestamp({ t: 1672531200, i: 1 }),
        t: Long(1)
      },
      optimeDurable: {
        ts: Timestamp({ t: 1672531200, i: 1 }),
        t: Long(1)
      },
      optimeDate: ISODate('2023-01-01T00:00:00.000Z'),
      optimeDurableDate: ISODate('2023-01-01T00:00:00.000Z'),
      lastHeartbeat: ISODate('2023-01-01T00:00:00.000Z'),
      lastHeartbeatRecv: ISODate('2023-01-01T00:00:00.000Z'),
      pingMs: Long(2),
      lastHeartbeatMessage: '',
      syncSourceHost: 'mongodb0.example.com:27017',
      syncSourceId: 0,
      infoMessage: '',
      configVersion: 3,
      configTerm: 1
    },
    {
      _id: 2,
      name: 'mongodb2.example.com:27017',
      health: 1,
      state: 2,
      stateStr: 'SECONDARY',
      uptime: 3400,
      optime: {
        ts: Timestamp({ t: 1672531200, i: 1 }),
        t: Long(1)
      },
      optimeDurable: {
        ts: Timestamp({ t: 1672531200, i: 1 }),
        t: Long(1)
      },
      optimeDate: ISODate('2023-01-01T00:00:00.000Z'),
      optimeDurableDate: ISODate('2023-01-01T00:00:00.000Z'),
      lastHeartbeat: ISODate('2023-01-01T00:00:00.000Z'),
      lastHeartbeatRecv: ISODate('2023-01-01T00:00:00.000Z'),
      pingMs: Long(3),
      lastHeartbeatMessage: '',
      syncSourceHost: 'mongodb0.example.com:27017',
      syncSourceId: 0,
      infoMessage: '',
      configVersion: 3,
      configTerm: 1
    }
  ],
  ok: 1,
  '$clusterTime': {
    clusterTime: Timestamp({ t: 1672531200, i: 1 }),
    signature: {
      hash: BinData(0, 'AAAAAAAAAAAAAAAAAAAAAAAAAAA='),
      keyId: Long(0)
    }
  },
  operationTime: Timestamp({ t: 1672531200, i: 1 })
}

使用场景

  • 查看复制集的当前状态
  • 检查复制集成员的健康状况
  • 查看复制集的选举信息
  • 监控复制集成员间的同步状态

成员管理命令

rs.add()

功能描述

向复制集添加新成员。

语法

javascript
rs.add(host, arbiterOnly)

参数说明

  • host:新成员的主机名和端口,格式为 hostname:port
  • arbiterOnly:布尔值,是否将新成员作为仲裁者

示例

javascript
// 添加普通成员
rs.add('mongodb3.example.com:27017');

// 添加仲裁者
rs.add('mongodb-arbiter.example.com:27017', true);

使用场景

  • 扩展复制集的规模
  • 替换故障的复制集成员
  • 添加仲裁者以提高选举可靠性

注意事项

  • 只能在主节点执行
  • 新成员需要使用相同的复制集名称启动
  • 新成员会自动从现有成员同步数据

rs.remove()

功能描述

从复制集移除成员。

语法

javascript
rs.remove(host)

参数说明

  • host:要移除的成员的主机名和端口

示例

javascript
rs.remove('mongodb3.example.com:27017');

使用场景

  • 移除故障的复制集成员
  • 缩减复制集的规模
  • 替换复制集成员前的准备

注意事项

  • 只能在主节点执行
  • 移除主节点会触发选举
  • 确保移除后仍有足够的投票成员

rs.addArb()

功能描述

向复制集添加仲裁者。

语法

javascript
rs.addArb(host)

参数说明

  • host:仲裁者的主机名和端口

示例

javascript
rs.addArb('mongodb-arbiter.example.com:27017');

使用场景

  • 添加仲裁者以打破投票僵局
  • 在不增加数据存储的情况下提高选举可靠性

注意事项

  • 仲裁者不存储数据,只参与投票
  • 一个复制集最多只能有一个仲裁者
  • 仲裁者的硬件要求较低

选举管理命令

rs.stepDown()

功能描述

使当前主节点降级为从节点,触发新的选举。

语法

javascript
rs.stepDown(stepDownSecs, secondaryCatchUpPeriodSecs)

参数说明

  • stepDownSecs:主节点降级后的等待时间(秒),期间不会参与选举
  • secondaryCatchUpPeriodSecs:等待从节点赶上主节点的时间(秒)

示例

javascript
// 使主节点降级,等待30秒后可以重新参与选举
rs.stepDown(30);

// 等待从节点赶上后再降级
rs.stepDown(60, 30);

使用场景

  • 计划维护时的主节点切换
  • 手动触发选举以测试复制集的故障转移能力
  • 解决主节点性能问题

注意事项

  • 只能在主节点执行
  • 会触发新的选举
  • 建议在低峰期执行

rs.freeze()

功能描述

冻结从节点,使其在指定时间内不参与选举。

语法

javascript
rs.freeze(seconds)

参数说明

  • seconds:冻结时间(秒)

示例

javascript
// 冻结从节点30秒
rs.freeze(30);

使用场景

  • 防止从节点在维护期间参与选举
  • 控制选举结果,确保特定节点成为主节点
  • 解决频繁选举的问题

注意事项

  • 只能在从节点执行
  • 冻结时间过后会自动解冻
  • 可以使用 rs.freeze(0) 立即解冻

rs.forceElect()

功能描述

强制当前节点发起选举。

语法

javascript
rs.forceElect()

示例

javascript
rs.forceElect();

使用场景

  • 手动触发选举,用于测试或恢复操作
  • 解决复制集无法自动选举主节点的问题

注意事项

  • 只能在从节点执行
  • 需要满足选举条件(如数据同步到足够新的时间点)
  • 使用时要谨慎,可能导致数据不一致

同步管理命令

rs.syncFrom()

功能描述

指定从节点的同步源。

语法

javascript
rs.syncFrom(host)

参数说明

  • host:同步源的主机名和端口

示例

javascript
rs.syncFrom('mongodb0.example.com:27017');

使用场景

  • 控制从节点的同步源,优化网络流量
  • 解决从节点同步延迟问题
  • 手动指定更可靠的同步源

注意事项

  • 只能在从节点执行
  • 临时设置,重启后会失效
  • 建议仅在特殊情况下使用

rs.printReplicationInfo()

功能描述

查看复制集的复制信息。

语法

javascript
rs.printReplicationInfo()

输出示例

configured oplog size:   1024MB
log length start to end: 10000secs (2.78hrs)
oplog first event time:  Thu Jan 01 2023 00:00:00 GMT+0000 (UTC)
oplog last event time:   Thu Jan 01 2023 02:46:40 GMT+0000 (UTC)
now:                     Thu Jan 01 2023 02:46:45 GMT+0000 (UTC)

使用场景

  • 查看 oplog 的大小和使用情况
  • 检查 oplog 是否足够大,避免数据丢失
  • 监控复制集的复制延迟

rs.printSlaveReplicationInfo()

功能描述

查看从节点的复制状态。

语法

javascript
rs.printSlaveReplicationInfo()

输出示例

source: mongodb1.example.com:27017
    syncedTo: Thu Jan 01 2023 02:46:40 GMT+0000 (UTC)
    0 secs (0 hrs) behind the primary

source: mongodb2.example.com:27017
    syncedTo: Thu Jan 01 2023 02:46:40 GMT+0000 (UTC)
    0 secs (0 hrs) behind the primary

使用场景

  • 查看从节点的同步延迟
  • 识别同步延迟较高的从节点
  • 监控从节点的复制状态

其他常用命令

rs.isMaster()

功能描述

检查当前节点是否为主节点。

语法

javascript
rs.isMaster()

输出示例

javascript
{
  ismaster: true,
  secondary: false,
  primary: 'mongodb0.example.com:27017',
  me: 'mongodb0.example.com:27017',
  electionId: ObjectId('7fffffff0000000000000001'),
  lastWrite: {
    opTime: {
      ts: Timestamp({ t: 1672531200, i: 1 }),
      t: Long(1)
    },
    lastWriteDate: ISODate('2023-01-01T00:00:00.000Z'),
    majorityOpTime: {
      ts: Timestamp({ t: 1672531200, i: 1 }),
      t: Long(1)
    },
    majorityWriteDate: ISODate('2023-01-01T00:00:00.000Z')
  },
  maxBsonObjectSize: 16777216,
  maxMessageSizeBytes: 48000000,
  maxWriteBatchSize: 100000,
  localTime: ISODate('2023-01-01T00:00:00.000Z'),
  logicalSessionTimeoutMinutes: 30,
  connectionId: 12345,
  minWireVersion: 0,
  maxWireVersion: 9,
  readOnly: false,
  ok: 1,
  '$clusterTime': {
    clusterTime: Timestamp({ t: 1672531200, i: 1 }),
    signature: {
      hash: BinData(0, 'AAAAAAAAAAAAAAAAAAAAAAAAAAA='),
      keyId: Long(0)
    }
  },
  operationTime: Timestamp({ t: 1672531200, i: 1 })
}

使用场景

  • 检查当前节点的角色
  • 确定复制集的主节点
  • 应用程序连接时的主节点检测

rs.status().members

功能描述

查看复制集所有成员的状态。

示例

javascript
// 查看所有成员的状态
var status = rs.status();
status.members.forEach(function(member) {
  print(member.name + ': ' + member.stateStr + ', ping: ' + member.pingMs + 'ms');
});

输出示例

mongodb0.example.com:27017: PRIMARY, ping: 1ms
mongodb1.example.com:27017: SECONDARY, ping: 2ms
mongodb2.example.com:27017: SECONDARY, ping: 3ms

使用场景

  • 快速查看所有成员的状态
  • 监控复制集成员的健康状况
  • 识别异常状态的成员

版本差异

MongoDB 4.0+ 新增命令

  • rs.reconfig() 支持 settings.electionTimeoutMillis 配置
  • 增强了 rs.status() 的输出信息
  • 支持 rs.stepDown()secondaryCatchUpPeriodSecs 参数

MongoDB 4.2+ 新增命令

  • 支持 rs.reconfig()settings.catchUpTakeoverDelayMillis 配置
  • 增强了 rs.printReplicationInfo() 的输出
  • 支持复制集成员的标签路由

MongoDB 5.0+ 新增命令

  • 支持 rs.reconfig()settings.chainingAllowed 配置
  • 增强了复制集的选举安全性
  • 支持更细粒度的复制集配置

最佳实践

配置管理最佳实践

  • 每次修改配置前备份当前配置
  • 避免在高峰期修改复制集配置
  • 使用 rs.conf() 验证配置修改是否成功
  • 限制 force 选项的使用

成员管理最佳实践

  • 复制集规模建议为 3-5 个成员
  • 仲裁者仅在必要时使用
  • 定期检查复制集成员的健康状况
  • 替换成员时确保数据同步完成

选举管理最佳实践

  • 避免频繁的手动选举
  • 使用 rs.stepDown() 进行计划内的主节点切换
  • 合理设置选举超时时间
  • 确保复制集成员的时钟同步

同步管理最佳实践

  • 监控从节点的同步延迟
  • 避免过度使用 rs.syncFrom()
  • 确保 oplog 大小足够大
  • 定期检查 oplog 的使用情况

常见问题(FAQ)

Q1: 如何查看复制集的当前主节点?

A1: 可以使用以下方法查看复制集的当前主节点:

  • 在 mongosh 中执行 rs.isMaster().primary
  • 查看 rs.status() 输出中的 members 数组,找到 stateStrPRIMARY 的成员
  • 使用 db.isMaster().primary 命令

Q2: 如何手动触发复制集选举?

A2: 可以使用以下方法手动触发复制集选举:

  • 在主节点执行 rs.stepDown(),使主节点降级,触发新的选举
  • 在从节点执行 rs.forceElect(),强制发起选举
  • 重启当前主节点,触发选举

Q3: 如何修改复制集成员的优先级?

A3: 修改复制集成员优先级的步骤:

  1. 获取当前配置:var config = rs.conf()
  2. 修改成员的优先级:config.members[0].priority = 2
  3. 应用新配置:rs.reconfig(config)
  4. 验证修改:rs.conf().members[0].priority

Q4: 复制集成员的健康状态为 0 怎么办?

A4: 如果复制集成员的健康状态为 0(不健康),可以采取以下措施:

  1. 检查成员的网络连接
  2. 检查成员的 MongoDB 进程是否运行
  3. 检查成员的日志文件,查找错误信息
  4. 尝试重启成员
  5. 如果问题仍然存在,考虑替换成员

Q5: 如何添加一个新的复制集成员?

A5: 添加新的复制集成员的步骤:

  1. 在新节点上安装 MongoDB
  2. 使用相同的复制集名称启动 MongoDB:mongod --replSet rs0
  3. 在主节点上执行 rs.add('newnode:27017')
  4. 等待新成员完成数据同步
  5. 使用 rs.status() 验证新成员的状态

Q6: 如何处理复制集的选举僵局?

A6: 处理复制集选举僵局的方法:

  1. 添加仲裁者,打破投票僵局
  2. 确保复制集成员的时钟同步
  3. 检查网络连接,确保成员之间可以通信
  4. 调整成员的优先级,确保有明确的主节点候选
  5. 使用 rs.forceElect() 强制发起选举

Q7: 如何查看复制集的同步延迟?

A7: 可以使用以下方法查看复制集的同步延迟:

  • 执行 rs.printSlaveReplicationInfo(),查看从节点的延迟
  • 查看 rs.status() 输出中成员的 optime 与主节点的差异
  • 使用监控工具(如 MongoDB Atlas、Ops Manager)查看同步延迟

Q8: 如何安全地移除复制集成员?

A8: 安全移除复制集成员的步骤:

  1. 确保移除后仍有足够的投票成员
  2. 如果要移除主节点,先使用 rs.stepDown() 使其降级
  3. 执行 rs.remove('member:27017') 移除成员
  4. 验证成员已成功移除
  5. 清理移除的成员的 MongoDB 数据(如果不再使用)