最近更换了办公地点。部署在本地docker环境里的mongo数据库不能使用了。原因是本地的ip地址变更。以前的mongo副本集的配置需要更新。处理完后,索性重新记录一下mongo副本集在docker中的部署流程。
我们先了解一下什么是事务,事务是一组对数据库执行的操作,这些操作作为一个不可分割的工作单元。在MongoDB中,一个事务可以涉及多个文档和多个集合。例如一个订单的下单过程,涉及到订单的生成,商品库存变化等多个文档的变化。在服务端执行过程中,如果某一段代码产生了错误。不使用事务的话,可能会导致订单生成来,商品库存却不变的情况发生。而使用事务后,整个下单将会作为一个整体,所有数据变化成功后,才会被最终写入数据库中。
在MongoDB中使用事务需要满足一些前提条件。以下是使用MongoDB事务的主要前提:
MongoDB版本:
副本集:
写操作:
支持的存储引擎:
我们主要来了解一下副本集。
MongoDB的副本集(Replica Set)是一种用于提供数据冗余和高可用性的数据库架构。副本集包含多个MongoDB实例,其中一个是主节点,其余是从节点。以下是副本集的一些关键概念和目的:
主节点(Primary):
从节点(Secondary):
数据冗余和高可用性:
自动故障转移:
部署多个节点:
参考:windows下搭建mongo副本集
# 创建3个实例,并设置他们副本集为 --replSet mongos,并创建每个实例的数据存储文件
mongodb1:
image: mongo:4.2.1
volumes:
- ./data/mongo1:/data/db
- ./MongoDB/copy:/copy
user: root
container_name: mongodb1
ports:
- 27018:27017
command: mongod --replSet mongos
restart: always
mongodb2:
image: mongo:4.2.1
volumes:
- ./data/mongo2:/data/db
- ./MongoDB/copy2:/copy
user: root
container_name: mongodb2
ports:
- 27019:27017
command: mongod --replSet mongos
restart: always
mongodb3:
image: mongo:4.2.1
volumes:
- ./data/mongo3:/data/db
- ./MongoDB/copy3:/copy
user: root
container_name: mongodb3
ports:
- 27020:27017
command: mongod --replSet mongos
restart: always
1. docker exec -it mongodb1 /bin/sh
2. 进入mongo,初始化副本集。
rs.initiate({
_id: "mongos",
members: [
{ _id : 0, host : "192.168.1.35:27017" },
{ _id : 1, host : "192.168.1.35:27018" },
{ _id : 2, host : "192.168.1.35:27019" }
]
});
# 因为我是本地环境的副本集,所以设置host为本地IP。
# 执行后的结果
{
"ok" : 1,
"operationTime" : Timestamp(1562140190, 1),
"$clusterTime" : {
"clusterTime" : Timestamp(1562140190, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
}
}
#使用 rs.status()检查副本集是否被正确设置
{
"set" : "mongos",
"date" : ISODate("2024-01-17T06:58:59.456Z"),
"myState" : 2,
"term" : NumberLong(7873),
"syncingTo" : "192.168.1.35:27019",
"syncSourceHost" : "192.168.1.35:27019",
"syncSourceId" : 1,
"heartbeatIntervalMillis" : NumberLong(2000),
"majorityVoteCount" : 2,
"writeMajorityCount" : 2,
"optimes" : {
"lastCommittedOpTime" : {
"ts" : Timestamp(1705474733, 1),
"t" : NumberLong(7873)
},
"lastCommittedWallTime" : ISODate("2024-01-17T06:58:53.638Z"),
"readConcernMajorityOpTime" : {
"ts" : Timestamp(1705474733, 1),
"t" : NumberLong(7873)
},
"readConcernMajorityWallTime" : ISODate("2024-01-17T06:58:53.638Z"),
"appliedOpTime" : {
"ts" : Timestamp(1705474733, 1),
"t" : NumberLong(7873)
},
"durableOpTime" : {
"ts" : Timestamp(1705474733, 1),
"t" : NumberLong(7873)
},
"lastAppliedWallTime" : ISODate("2024-01-17T06:58:53.638Z"),
"lastDurableWallTime" : ISODate("2024-01-17T06:58:53.638Z")
},
"lastStableRecoveryTimestamp" : Timestamp(1705474703, 1),
"lastStableCheckpointTimestamp" : Timestamp(1705474703, 1),
"members" : [
{
"_id" : 0,
"name" : "192.168.1.35:27018",
"ip" : "192.168.1.35",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 20000,
"optime" : {
"ts" : Timestamp(1705474733, 1),
"t" : NumberLong(7873)
},
"optimeDate" : ISODate("2024-01-17T06:58:53Z"),
"syncingTo" : "192.168.1.35:27019",
"syncSourceHost" : "192.168.1.35:27019",
"syncSourceId" : 1,
"infoMessage" : "",
"configVersion" : 100459,
"self" : true,
"lastHeartbeatMessage" : ""
},
{
"_id" : 1,
"name" : "192.168.1.35:27019",
"ip" : "192.168.1.35",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 19965,
"optime" : {
"ts" : Timestamp(1705474733, 1),
"t" : NumberLong(7873)
},
"optimeDurable" : {
"ts" : Timestamp(1705474733, 1),
"t" : NumberLong(7873)
},
"optimeDate" : ISODate("2024-01-17T06:58:53Z"),
"optimeDurableDate" : ISODate("2024-01-17T06:58:53Z"),
"lastHeartbeat" : ISODate("2024-01-17T06:58:58.811Z"),
"lastHeartbeatRecv" : ISODate("2024-01-17T06:58:58.809Z"),
"pingMs" : NumberLong(1),
"lastHeartbeatMessage" : "",
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"infoMessage" : "",
"electionTime" : Timestamp(1705454782, 1),
"electionDate" : ISODate("2024-01-17T01:26:22Z"),
"configVersion" : 100459
},
{
"_id" : 2,
"name" : "192.168.1.35:27020",
"ip" : "192.168.1.35",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 19965,
"optime" : {
"ts" : Timestamp(1705474733, 1),
"t" : NumberLong(7873)
},
"optimeDurable" : {
"ts" : Timestamp(1705474733, 1),
"t" : NumberLong(7873)
},
"optimeDate" : ISODate("2024-01-17T06:58:53Z"),
"optimeDurableDate" : ISODate("2024-01-17T06:58:53Z"),
"lastHeartbeat" : ISODate("2024-01-17T06:58:58.810Z"),
"lastHeartbeatRecv" : ISODate("2024-01-17T06:58:58.810Z"),
"pingMs" : NumberLong(1),
"lastHeartbeatMessage" : "",
"syncingTo" : "192.168.1.35:27019",
"syncSourceHost" : "192.168.1.35:27019",
"syncSourceId" : 1,
"infoMessage" : "",
"configVersion" : 100459
}
],
"ok" : 1,
"$clusterTime" : {
"clusterTime" : Timestamp(1705474733, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
},
"operationTime" : Timestamp(1705474733, 1)
}
配置成功后,我们的mongo命令行会显示当前实例是主节点(PRIMARY)or子节点(SECONDARY)
当我的ip变化后,之前的配置就无效了,mongo的命令行也会显示当前的mongo节点为OTHER
rs.initiate({
_id: "mongos",
members: [
{ _id : 0, host : "192.168.1.35:27017" },
{ _id : 1, host : "192.168.1.35:27018" },
{ _id : 2, host : "192.168.1.35:27019" }
]
});
---
Enable MongoDB's free cloud-based monitoring service, which will then receive and display
metrics about your deployment (disk utilization, CPU, operation statistics, etc).
The monitoring data will be available on a MongoDB website with a unique URL accessible to you
and anyone you share the URL with. MongoDB may use this information to make product
improvements and to suggest MongoDB products and deployment options to you.
To enable free monitoring, run the following command: db.enableFreeMonitoring()
To permanently disable this reminder, run the following command: db.disableFreeMonitoring()
---
mongos:OTHER>
此时3个mongo实例都是宕机的OTHER状态,既非主节点也非子节点。需要我们更新members成员的IP信息。
#进入任意mongo实例
#获取配置信息
mongos:OTHER>cfg = rs.conf()
#更新配置信息
mongos:OTHER>cfg.members[0].host="192.168.6.3:27018"
mongos:OTHER>cfg.members[1].host="192.168.6.3:27018"
mongos:OTHER>cfg.members[2].host="192.168.6.3:27018"
# 使用rs.reconfig(cfg)重设配置,此时会抛错
mongos:OTHER>rs.reconfig(cfg)
{
"operationTime" : Timestamp(1705368470, 1),
"ok" : 0,
"errmsg" : "replSetReconfig should only be run on PRIMARY, but my state is REMOVED; use the \"force\" argument to override",
"code" : 10107,
"codeName" : "NotMaster",
"$clusterTime" : {
"clusterTime" : Timestamp(1705368470, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
}
}
#添加force,强制执行
mongos:OTHER> rs.reconfig(cfg,{force:true})
{
"ok" : 1,
"$clusterTime" : {
"clusterTime" : Timestamp(1705368470, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
},
"operationTime" : Timestamp(1705368470, 1)
}
成功后,副本集就又可以正常使用了。