MongoDB主从切换实战:如何让指定从库“精准”升级为主库?保姆级教程!

问题描述

MongoDB 4.4.9是PSS架构:

主库 10.20.17.51

从库 10.20.17.52

从库 10.20.17.53

现在要主库切换后,让从库10.20.17.52变成主库

1. 确认同步情况

1.1 从库查看

db.printSlaveReplicationInfo();

查看主从是否同步完成,等同步完成后才可以切换

复制代码
wewint1:SECONDARY> rs.printSecondaryReplicationInfo()
source: 10.20.17.52:27017
	syncedTo: Mon Sep 01 2025 10:34:22 GMT+0800 (CST)
	-1 secs (0 hrs) behind the primary 
source: 10.20.17.53:27017
	syncedTo: Mon Sep 01 2025 10:34:20 GMT+0800 (CST)  < 看时间戳是这个从库慢一点
	1 secs (0 hrs) behind the primary 

为什么会出现 -1 secs?

1)时间漂移(Clock Skew)

rs.printSecondaryReplicationInfo() 是通过比较 主节点与从节点的系统时间 和 oplog 时间戳 来计算延迟的。

如果主从节点系统时间不一致(即使只差 1 秒),就可能出现负值。

2)显示精度问题

当从库同步非常接近主库(<1秒),MongoDB 的计算逻辑可能显示为 -1,实际表示 "几乎同步"。

2. 方法1:修改优先级调整主从

通过 rs.status() 查看当前副本集状态,找到members需要切换为Primary节点的数组下标,

cfg.members0 中的 0 就是数组索引,表示第 1 个成员

复制代码
wewint1:SECONDARY> rs.conf().members
[
	{
		"_id" : 0,
		"host" : "10.20.17.51:27017",
		"arbiterOnly" : false,
		"buildIndexes" : true,
		"hidden" : false,
		"priority" : 10,
		"tags" : {
			
		},
		"slaveDelay" : NumberLong(0),
		"votes" : 1
	},
	{
		"_id" : 1,
		"host" : "10.20.17.52:27017",
		"arbiterOnly" : false,
		"buildIndexes" : true,
		"hidden" : false,
		"priority" : 5,
		"tags" : {
			
		},
		"slaveDelay" : NumberLong(0),
		"votes" : 1
	},
	{
		"_id" : 3,
		"host" : "10.20.17.53:27017",
		"arbiterOnly" : false,
		"buildIndexes" : true,
		"hidden" : false,
		"priority" : 3,
		"tags" : {
			
		},
		"slaveDelay" : NumberLong(0),
		"votes" : 1
	}
]

将其优先级priority设置成members中最大的值,rs.conf()获取到当前配置,重新配置rs.reconfig(config)就修改成功了。

主库执行:

让从库10.20.17.52的优先级是高于其他两个节点的

复制代码
PRIMARY> config = rs.conf()
PRIMARY> config.members[1].priority = 15
PRIMARY> rs.reconfig(config)

LOGS:
PRIMARY> rs.reconfig(config)
{
        "ok" : 1,
        "$clusterTime" : {
                "clusterTime" : Timestamp(1756696295, 1),
                "signature" : {
                        "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                        "keyId" : NumberLong(0)
                }
        },
        "operationTime" : Timestamp(1756696295, 1)
}

priority有效范围是 0--1000 的浮点数(含 0 和 1000),默认值 1。

说明:

mongodb中rs.reconfig(config)解释

底层调用的是 replSetReconfig 命令,只能在主节点上执行(除非加 {force:true})

1)对集群的影响

  • 短暂不可写:主节点收到命令后,会先降级(step-down),触发一轮选举,期间所有写操作都会被拒绝;默认选举耗时 ≤12 s。

  • 传播顺序:新配置先在主节点本地生效,再通过心跳推送到其它节点,只有当大多数投票节点都装上新配置后命令才返回成功。

  • 一次只能改一个投票成员:从 4.4 开始,如果只是想添加/删除/改票,默认一次只能改 1 个投票成员,否则会报错;想批量改需 {force:true},但强制模式可能回滚已多数提交的写,生产慎用。

  • 回滚风险:如果新配置把某些还没追上 oplog 的节点踢出投票组,可能导致旧主节点的已确认写被回滚。

2)版本差异

  • 4.2 以前:主节点降级时会关闭全部客户端连接;4.2 起仅终止正在进行的写,不踢连接。

  • 4.4 起:

    -- 默认等待多数投票节点安装新配置,最多可设 maxTimeMS 超时。

每次最多只允许1 个投票成员变动;如需一次改多个,必须 {force:true}。

  • 5.0 起:
    新增节点在达到 SECONDARY 状态前会被标记 newlyAdded: true,这段时间不算投票成员,防止误选举。
    如果修改后的配置会改变隐式默认写关注,需要先显式 setDefaultRWConcern,否则 rs.reconfig() 失败。

确认当前主从状态

复制代码
rs.status()

3. 方法2:手动触发主库降级(只有在优先级一样的情况下才会用)

登录 ADMIN 账号

复制代码
mongo --host 10.20.17.51:27017 -u <replAdminUser> -p <password> --authenticationDatabase admin

PRIMARY> rs.stepDown(60)

LOGS:
{
        "ok" : 1,
        "$clusterTime" : {
                "clusterTime" : Timestamp(1756697187, 1),
                "signature" : {
                        "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                        "keyId" : NumberLong(0)
                }
        },
        "operationTime" : Timestamp(1756697187, 1)
}

说明:

1)60秒是必须的吗?

rs.stepDown(60) 中的 60 是"强制冷却"秒数。

在这段时间内,当前节点不会再次竞选主库,让其他有资格节点有充足时间完成选举并稳定成为新主库。

最小允许值为 5 秒。可以改为30秒吗?可以但是没必要。rs.stepDown(30),只要集群网络、节点状态都正常,30 秒通常足够完成选举。

2) 选举的顺序

主库 10.20.17.51 执行 rs.stepDown(60)降低后,是不是从库优先级高的变成主库呢?

priority = 0:永远没有资格成为主库(只能当从库)

priority > 0:都有同等机会被选举为主库,不是"谁高谁上"。

当主库 rs.stepDown() 或宕机后,剩余节点会触发选举,投票规则如下:

1)最新 optime(同步数据最新的节点)优先

如果 10.20.17.52 的 oplog 比 10.20.17.53 更新,它就更容易被选举为主库。

rs.printSecondaryReplicationInfo()

2)优先级只是"参与资格"

只要 priority > 0,就都可以被选,不是优先级高的就一定赢。

3)"多数派"投票

需要获得大多数存活节点的投票才能当选主库

相关推荐
IT小白杨19 小时前
海外业务账号安全保障:主流浏览器产品底层机制对比
数据库·python·安全·自动化·安全架构·指纹浏览器
张洛闻Eren1 天前
MySQL 维护稳定系统【MySQL第二课】
linux·数据库·mysql·云原生
布莱克6051 天前
理解索引:从概念到实践
数据库·mysql
我不是疯子是傻子1 天前
Qt CAN通信周期发送抖动?实测定时器精度校准与时间戳补偿方案
开发语言·数据库·qt
这个DBA有点耶1 天前
数据库迁移怎么做到“零翻车“:金仓 KDMS/KDTS/KFS 工具链实测
数据库·架构·dba
2501_937860941 天前
MySQL联合查询(多表查询)
数据库·mysql
名字还没想好☜1 天前
Next.js 用 Server Components 直连数据库:去掉 API 层的边界,和三条别踩的安全红线
前端·javascript·数据库·安全·react·next.js
迷迭香yy1 天前
行业板块轮动因子实战从板块资金到因子建模的本地化Python全流程
数据库·人工智能·python
SelectDB1 天前
抖音集团 实时数据仓库:Apache Doris / SelectDB 的技术能力与实践
数据库
SelectDB1 天前
网易 日志与时序数据分析:Apache Doris / SelectDB 的技术能力与实践
数据库