外观
MongoDB 复制集管理命令
命令分类
MongoDB 复制集管理命令主要分为以下几类:
- 配置管理命令:用于查看和修改复制集配置
- 状态查询命令:用于查看复制集状态和成员信息
- 成员管理命令:用于添加、移除和修改复制集成员
- 选举管理命令:用于控制复制集选举
- 同步管理命令:用于管理复制集成员间的同步
命令执行方式
复制集管理命令主要通过以下方式执行:
- mongosh shell:在 mongosh 中直接执行
- 驱动程序 API:通过 MongoDB 驱动程序调用
- HTTP API:通过 MongoDB 的 HTTP 接口调用(仅适用于某些命令)
命令权限要求
执行复制集管理命令通常需要:
- 连接到复制集的主节点(某些命令也可以在从节点执行)
- 具有
clusterManager或clusterAdmin角色 - 对于分片集群中的复制集,可能需要额外的权限
配置管理命令
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数组,找到stateStr为PRIMARY的成员 - 使用
db.isMaster().primary命令
Q2: 如何手动触发复制集选举?
A2: 可以使用以下方法手动触发复制集选举:
- 在主节点执行
rs.stepDown(),使主节点降级,触发新的选举 - 在从节点执行
rs.forceElect(),强制发起选举 - 重启当前主节点,触发选举
Q3: 如何修改复制集成员的优先级?
A3: 修改复制集成员优先级的步骤:
- 获取当前配置:
var config = rs.conf() - 修改成员的优先级:
config.members[0].priority = 2 - 应用新配置:
rs.reconfig(config) - 验证修改:
rs.conf().members[0].priority
Q4: 复制集成员的健康状态为 0 怎么办?
A4: 如果复制集成员的健康状态为 0(不健康),可以采取以下措施:
- 检查成员的网络连接
- 检查成员的 MongoDB 进程是否运行
- 检查成员的日志文件,查找错误信息
- 尝试重启成员
- 如果问题仍然存在,考虑替换成员
Q5: 如何添加一个新的复制集成员?
A5: 添加新的复制集成员的步骤:
- 在新节点上安装 MongoDB
- 使用相同的复制集名称启动 MongoDB:
mongod --replSet rs0 - 在主节点上执行
rs.add('newnode:27017') - 等待新成员完成数据同步
- 使用
rs.status()验证新成员的状态
Q6: 如何处理复制集的选举僵局?
A6: 处理复制集选举僵局的方法:
- 添加仲裁者,打破投票僵局
- 确保复制集成员的时钟同步
- 检查网络连接,确保成员之间可以通信
- 调整成员的优先级,确保有明确的主节点候选
- 使用
rs.forceElect()强制发起选举
Q7: 如何查看复制集的同步延迟?
A7: 可以使用以下方法查看复制集的同步延迟:
- 执行
rs.printSlaveReplicationInfo(),查看从节点的延迟 - 查看
rs.status()输出中成员的optime与主节点的差异 - 使用监控工具(如 MongoDB Atlas、Ops Manager)查看同步延迟
Q8: 如何安全地移除复制集成员?
A8: 安全移除复制集成员的步骤:
- 确保移除后仍有足够的投票成员
- 如果要移除主节点,先使用
rs.stepDown()使其降级 - 执行
rs.remove('member:27017')移除成员 - 验证成员已成功移除
- 清理移除的成员的 MongoDB 数据(如果不再使用)
