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.members[0] 中的 [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)"多数派"投票

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

相关推荐
是有头发的程序猿9 小时前
电商开发日志:淘宝图片搜索商品列表(二)
数据库·爬虫·python
DemonAvenger9 小时前
从零到精通:数据库连接池的设计、优化与实战经验分享
数据库·sql·性能优化
海天瑞声AI10 小时前
“AI 正回应时,也可随时打断?”揭秘 GPT Realtime × Gemini 的“全双工魔力”,都离不开它!
数据库·人工智能·语音识别
GBASE10 小时前
“G”术时刻:南大通用GBase 8c数据库权限管理场景实践(一)
数据库
蓝倾97610 小时前
1688拍立淘接口对接实战案例
java·开发语言·数据库·python·电商开放平台·开放api接口
GBASE10 小时前
GBASE南大通用技术分享:迁移项目数据抽样核对方案简述
数据库
Vae_Mars10 小时前
C语言中的运算符
数据库·单片机·mongodb
不要再敲了10 小时前
Java 方法:从定义调用到重载,入门到面试全攻略
数据库·oracle
曾经的三心草10 小时前
微服务的编程测评系统19-我的消息功能-竞赛排名功能
java·数据库·微服务