# MongoDB

# 复制

复制就是在多台服务器上分布并管理数据库服务器。MongoDB 提供了两种复制风格:主从复制和副本集

两种方式都是在一个主节点进行写操作(写入的数据被异步地应用到所有从节点上),并从节点上读取数据。

主从复制和副本集使用了相同的复制机制,但是副本集还能保证自动故障转移:如果主节点由于某些原因下线了,可能的话,会自动将一个从节点提升为主节点。

# 副本集

副本集是对主从复制的一种完善,也是推荐的 MongoDB 复制策略。

# 搭建副本集

  1. 启动三个实例(以副本集模式)
mongod --replSet myapp --dbpath /data/node1 --port 40000
mongod --replSet myapp --dbpath /data/node2 --port 40001
mongod --replSet myapp --dbpath /data/arbiter --port 40002
  1. 初始化副本集
mongo --host localhost --port 40000
> rs.initiate()
  1. 添加其他成员节点
> rs.add("localhost:40001")
> rs.add("localhost:40002", {arbiterOnly: true}) # 创建一个仲裁节点
  1. 查看副本集信息
myapp:PRIMARY> db.isMaster()
{
	"hosts" : [
		"localhost:40000",
		"localhost:40001"
	],
	"arbiters" : [
		"localhost:40002"
	],
	"setName" : "myapp",
	"setVersion" : 3,
	...
  1. 查看副本集详细信息
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,
	...

# 使用副本集

  1. 添加数据
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
  1. 查看数据复制情况
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()

# 重新选举主节点

  1. 杀掉主节点
myapp:PRIMARY> db.shutdownServer()
  1. 从节点被选举为新的主节点
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",
  1. 恢复后老的主节点变为的从节点
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",
上次更新: 2/13/2025, 3:29:47 AM