目录
- [1. 分析mongo副本集 Election succeeded 的全过程:](#1. 分析mongo副本集 Election succeeded 的全过程:)
- [2. 从日志里面看到数据库一致性的对比吗?](#2. 从日志里面看到数据库一致性的对比吗?)
- 模拟主备不同步,副本集切换
1. 分析mongo副本集 Election succeeded 的全过程:
从提供的日志中,我们可以看到以下关键步骤描述了副本集中的选举过程:
-
Election Triggered : 选举过程开始于一个节点(10.10.98.127:3692)接收到
replSetStepUp
请求,这通常意味着该节点决定自己应该成为新的主节点。 -
Election Process : 随后,该节点开始选举过程(
Starting an election due to step up request
),并跳过干运行(dry run),直接进行选举(Skipping dry run and running for election
)。 -
Vote Requests : 该节点作为候选人,向其他成员发送投票请求(
VoteRequester
),请求它们投票支持它成为新的主节点。 -
Vote Responses : 从日志中我们可以看到,至少有一个节点(10.10.98.127:3692)对该候选人的投票请求做出了肯定的响应(
VoteRequester processResponse
),而另一个节点(10.10.98.123:7315)由于正在关闭(ShutdownInProgress
),未能成功投票。 -
Election Success : 由于收到了足够的肯定票数,选举成功,该节点(10.10.98.125:4933)假设了主节点的角色(
Election succeeded, assuming primary role
)。 -
State Transition : 随后,该节点的状态转变为
PRIMARY
(Replica set state transition
),这意味着它现在是副本集的主节点。 -
Sync Source Reset : 新的主节点重置了其同步源(
Resetting sync source to empty
),准备开始接受写操作。 -
Catch-up Mode : 新的主节点进入追赶模式(
Entering primary catch-up mode
),以确保它拥有最新的数据。 -
Topology Changes: 随着新主节点的确立,副本集的拓扑结构也随之更新,其他节点的状态也相应更新。
2. 从日志里面看到数据库一致性的对比吗?
在提供的日志中,并没有直接的数据库一致性对比操作的记录。MongoDB副本集的一致性通常是通过复制主节点的操作日志(oplog)来维护的。当一个节点成为新的主节点时,其他次要节点会从这个新的主节点同步数据,以确保数据的一致性。
在选举成功后,新的主节点(10.10.98.125:4933)会开始接受写操作,而其他节点则会尝试与其同步来更新自己的数据。然而,日志中并没有显示具体的数据对比或一致性检查的过程。通常,这些细节在副本集的日常操作中是自动处理的,除非出现同步问题或数据不一致的情况,否则不会在日志中特别记录。
模拟主备不同步,副本集切换
步骤
人为制造数据不一致的情况在测试环境中可以模拟,但请谨慎操作,因为这可能会影响数据库的稳定性。以下是模拟数据不一致的步骤:
-
确定当前的主节点 :
首先,你需要确定哪个节点是当前的主节点。可以通过以下命令查看副本集的状态:
javascriptrs.status()
-
在主节点上执行写操作 :
选择一个数据库和集合,然后执行写操作。例如,向
testDB
数据库的testCollection
集合插入文档:javascriptuse testDB1 db.testCollection.insert({data1: "This is a test document."})
-
隔离主节点 :
接下来,你需要从网络层面隔离这个主节点,以阻止它与其他副本集成员同步。这通常涉及到修改网络配置或使用网络工具。例如,你可以使用
iptables
命令在Linux系统上阻止来自特定端口的流量:bashsudo iptables -A INPUT -p tcp --dport 27017 -j DROP
这个命令会阻止所有进入MongoDB默认端口(27017)的TCP流量。请注意,你应该根据实际使用的端口和IP地址调整这个命令。
删除 iptables 规则 https://blog.csdn.net/hezuijiudexiaobai/article/details/130659181
备库加锁
csharp
mongo -uroot -p qm7gkmnDr_oPl1di
db.fsyncLock()
-
确认数据不一致 :
在隔离主节点之后,尝试在其他从节点上读取数据,检查是否能够看到刚才写入的数据。由于主节点被隔离,这些数据不会同步到其他节点,从而产生数据不一致。
-
恢复网络连接 :
一旦你完成了测试,应该恢复主节点的网络连接,以便副本集可以恢复正常操作。使用以下命令撤销之前设置的
iptables
规则:bashsudo iptables -D INPUT -p tcp --dport 27017 -j DROP
-
重新同步数据 :
网络连接恢复后,副本集将尝试重新同步数据。你可以使用
rs.syncFrom
命令强制一个从节点从特定的同步源开始同步:javascriptdb.runCommand({replSetSyncFrom: "syncSourceMemberName"})
其中
syncSourceMemberName
是你选择的同步源成员的名字。
注意事项:
- 请确保在测试环境中执行这些操作,避免在生产环境中造成数据丢失或服务中断。
- 在进行这些操作之前,确保你已经备份了所有重要数据。
- 根据你的MongoDB版本和配置,命令和步骤可能会有所不同。
人为制造数据不一致是一种高级操作,通常只在特定的测试场景下进行。在大多数情况下,你应该尽量保持副本集的同步和一致性。
not master and slaveOk=false
错误信息 "not master and slaveOk=false"
表示你尝试在一个非主节点上执行操作,而且 slaveOk
参数没有被设置为 true
。在MongoDB副本集中,大多数读操作默认只能针对主节点进行,从节点默认不接受普通查询操作,除非 slaveOk
设置为 true
。
要解决这个问题,你可以在查询时添加 slaveOk
选项,这允许你的操作在非主节点上执行。以下是如何修改你的命令以包含 slaveOk
:
javascript
db.getMongo().setReadPref('secondary');
db.system.log.find().sort({$natural: -1}).limit(1)
或者直接使用 slaveOk
参数:
javascript
db.system.log.find().slaveOk().sort({$natural: -1}).limit(1)
这两种方法都会让你的查询可以在从节点上执行。第一种方法通过设置读取偏好来实现,第二种方法直接在查询上设置 slaveOk
。
解释:
db.getMongo().setReadPref('secondary')
:这行代码设置了全局的读取偏好为从节点(secondary)。这意味着所有后续的读操作都会尝试在从节点上执行。slaveOk()
:这个方法是直接在查询上设置,允许这个特定的查询在从节点上执行。
通常,查看日志的操作不会对数据库性能产生显著影响,因此可以在从节点上执行。但是,确保在生产环境中合理使用这些设置,以避免不必要的负载。
错误信息 "not master and slaveOk=false"
表示你正在尝试在一个从节点上执行 show dbs
命令,而这个命令默认只能在主节点上执行。在从节点上执行需要设置 slaveOk
为 true
。
你已经尝试使用 db.getMongo().setReadPref('secondary')
来设置读取偏好,但这个命令实际上并没有改变 slaveOk
的值。你需要使用 setSlaveOk
方法来显式地允许从节点上的查询。
在MongoDB Shell中,你可以使用以下命令来允许从节点上的查询:
javascript
db.getMongo().setSlaveOk();
或者,你可以直接使用:
javascript
db.setSlaveOk();
这将允许当前数据库连接在从节点上执行查询。然后,你应该能够执行 show dbs
命令:
javascript
show dbs;
请注意,setSlaveOk
只影响当前的数据库连接。如果你打开一个新的MongoDB Shell连接,你需要再次执行这个命令。
另外,从MongoDB 3.2版本开始,slaveOk
已经被标记为过时,建议使用 readPreference
来代替。但是,对于你的需求来说,使用 setSlaveOk
应该足够了。
确实,MongoDB 副本集在主节点失去连接时会触发选举过程,以确保始终有一个主节点来处理写操作。如果你希望模拟数据不一致而不触发选举,可以尝试以下方法:
其他方案
方法一:使用 rs.stepDown()
命令
-
确定主节点 :
使用
rs.status()
命令确定当前的主节点。 -
执行
rs.stepDown()
:在主节点上执行
rs.stepDown()
命令,使主节点主动放弃主节点地位并触发选举。你可以指定stepDown
命令的force
选项来确保即使无法选举出新的主节点也会执行。javascriptdb.runCommand({replSetStepDown: 60, force: true})
这个命令会使当前的主节点在 60 秒内拒绝任何新的选举。如果在此期间没有其他节点当选,副本集将没有主节点。
-
执行写操作 :
在主节点上执行写操作,然后迅速将该节点从副本集中移除或停止其
mongod
进程。 -
检查数据一致性 :
在其他节点上检查是否能读取到刚才写入的数据。
-
恢复主节点 :
恢复主节点的服务,并观察副本集如何重新选举和同步数据。
方法二:使用 rs.slaveOk
命令
-
设置
slaveOk
:在从节点上设置
slaveOk
为true
,允许从节点处理查询。javascriptdb.getMongo().setReadPref('secondary');
-
执行写操作 :
在主节点上执行写操作。
-
停止主节点的复制进程 :
停止主节点的复制进程,但不完全关闭数据库服务。这可以通过停止 oplog 的写入来实现,例如,通过设置
oplogSize
为0
(不推荐在生产环境中使用)。 -
执行更多写操作 :
在主节点上执行更多写操作。
-
检查数据一致性 :
在其他节点上检查是否能读取到刚才写入的数据。
方法三:使用 mongod
配置文件
-
修改配置文件 :
在
mongod.conf
文件中设置replSet
配置,并设置enableMajorityReadConcern=false
以允许从节点在没有同步最新数据的情况下提供读服务。 -
重启 MongoDB 服务 :
重启 MongoDB 服务以应用新的配置。
-
执行写操作 :
在主节点上执行写操作。
-
隔离主节点 :
通过修改网络配置或使用防火墙规则,隔离主节点,使其无法与其他节点通信。
-
检查数据一致性 :
在其他节点上检查是否能读取到刚才写入的数据。
注意事项
- 这些方法可能会影响数据库的稳定性和数据的完整性,请在测试环境中进行。
- 确保在进行这些操作之前备份所有重要数据。
- 在生产环境中,应尽量避免人为制造数据不一致的情况。
通过这些方法,你可以在不触发选举的情况下模拟数据不一致的情况。