# MongoDB
# 复制
复制就是在多台服务器上分布并管理数据库服务器。MongoDB 提供了两种复制风格:主从复制和副本集。
两种方式都是在一个主节点进行写操作(写入的数据被异步地应用到所有从节点上),并从节点上读取数据。
主从复制和副本集使用了相同的复制机制,但是副本集还能保证自动故障转移:如果主节点由于某些原因下线了,可能的话,会自动将一个从节点提升为主节点。
# 副本集
副本集是对主从复制的一种完善,也是推荐的 MongoDB 复制策略。
# 搭建副本集
- 启动三个实例(以副本集模式)
mongod --replSet myapp --dbpath /data/node1 --port 40000
mongod --replSet myapp --dbpath /data/node2 --port 40001
mongod --replSet myapp --dbpath /data/arbiter --port 40002
- 初始化副本集
mongo --host localhost --port 40000
> rs.initiate()
- 添加其他成员节点
> rs.add("localhost:40001")
> rs.add("localhost:40002", {arbiterOnly: true}) # 创建一个仲裁节点
- 查看副本集信息
myapp:PRIMARY> db.isMaster()
{
"hosts" : [
"localhost:40000",
"localhost:40001"
],
"arbiters" : [
"localhost:40002"
],
"setName" : "myapp",
"setVersion" : 3,
...
- 查看副本集详细信息
myapp:PRIMARY> rs.status()
{
"set" : "myapp",
"date" : ISODate("2020-10-23T14:56:34.132Z"),
"myState" : 1,
"term" : NumberLong(1),
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"heartbeatIntervalMillis" : NumberLong(2000),
"majorityVoteCount" : 2,
"writeMajorityCount" : 2,
...
# 使用副本集
- 添加数据
myapp:PRIMARY> use bookstore
myapp:PRIMARY> db.books.insert({title: "Oliver Twist"})
myapp:PRIMARY> show dbs
admin 0.000GB
bookstore 0.000GB
config 0.000GB
local 0.000GB
- 查看数据复制情况
mongo localhost:40001
myapp:SECONDARY> show dbs
admin 0.000GB
bookstore 0.000GB
config 0.000GB
local 0.000GB
myapp:SECONDARY> use bookstore
switched to db bookstore
myapp:SECONDARY> db.books.find()
{ "_id" : ObjectId("5f92efebf1f02b90851570dc"), "title" : "Oliver Twist" }
默认 Secondary 不允许读写,需要设置:rs.slaveOk()
# 重新选举主节点
- 杀掉主节点
myapp:PRIMARY> db.shutdownServer()
- 从节点被选举为新的主节点
mongo localhost:40001
myapp:PRIMARY> db.isMaster()
{
"hosts" : [
"localhost:40000",
"localhost:40001"
],
"arbiters" : [
"localhost:40002"
],
"setName" : "myapp",
"setVersion" : 3,
"ismaster" : true,
"secondary" : false,
"primary" : "localhost:40001",
- 恢复后老的主节点变为的从节点
mongo localhost:40000
myapp:SECONDARY> db.isMaster()
{
"hosts" : [
"localhost:40000",
"localhost:40001"
],
"arbiters" : [
"localhost:40002"
],
"setName" : "myapp",
"setVersion" : 3,
"ismaster" : false,
"secondary" : true,
"primary" : "localhost:40001",
"me" : "localhost:40000",