文章目录
- MongoDB介绍
 - 主要用途和特点
 - 对比关系型数据库
 - 和关系型数据库最大的不同
 - 什么时候使用MongoDB
 - MongoDB数据结构
 - MongoDB参考资料
 
- MongoDB部署和访问
 - 二进制安装
 - 脚本安装
 - MongoDB后台管理shell
 - mongodb数据库命令
 - mongo的help
 - db.mycoll.help()
 
- mongosh的help
 - show dbs
 - use dbname
 - mongosh的安装
 - 可视化管理工具
 - Python访问MongoDB
 
- MongoDB管理
 - 库的操作
 - 集合(表)的操作
 - 灵活的insert
 
- 记录(文档操作)
 
- 用户和权限管理
 - 用户验证库
 - 开启用户认证
 - 用户管理说明
 
- 系统内置角色
 - superuser用户
 - 普通用户
 
- 查看所有用户信息
 
- MongoDB复制集
 - 复制集架构
 - 复制集实现
 - 1.配置mongo.conf文件
 - 2.初始化设置,
 - 3.执行rs.initiate(初始化设置的函数名)
 
- 查看复制集状态
 - slaveOk()
 
- secondary节点只能读,不能写
 - 添加和删除节点
 
- 复制集角色说明
 - 主要角色
 - 主节点[Primary]
 - 副本节点[Secondary]
 - 仲裁者[Arbiter]
 
- Primary选举实现
 - 其他角色
 - rs.conf()查看优先级
 
- MongoDB备份恢复
 - 备份恢复的两个工具
 - 1.mongoexport/mongoimport
 - 2.mongodump/mongorestore
 - 两种工具的对比
 
- mongoexport/mongoimport
 - 导出工具 mongoexport
 - 导出json格式示例
 - 导出csv格式示例
 
- 导入工具mongoimport
 - 导入示例
 

MongoDB介绍
MongoDB并非芒果mango的意思,而是源于Humongous(巨大的)一词。
MongoDB是由总部位于美国纽约的上市公司MongoDB lnc(原名10gen)基于C++编写的分布式文档数据库。
 之所以称为文档数据库,是因为MongoDB保存的是"JSON Document",并非一般的PDF,WORD文档。MongoDB内部使用类似于Json的bson格式。
内部执行引擎为JS解释器。把文档存储成bson结构,在查询时转换为JS对象,并可以通过熟悉的js语法来操作。
 MongoDB被称为最像RDBMS的NoSQL,支持事务,锁,索引类似于MySQL。
官方网站:https://www.mongodb.com/
 Github:https://github.com/mongodb

数据库排名
 https://db-engines.com/en/ranking
 https://db-engines.com/en/ranking_trend/system/MongoDB
 
 
主要用途和特点
主要用途
  1.应用数据库,比如:存储银行,保险公司流水信息,类似于Oracle,MySQL海量数据处理,大数据分析
  2.网站数据、缓存等大尺寸、低价值的数据
  3.在高伸缩性的场景,用于对象及JSON数据的存储。
 
主要特点
  1.灵活动态的文档建模
  2.JSON数据模型比较适合开发者
  3.支持高可用
  4.水平扩展可以支撑很大数据量和并发
  5.存储空间占用相对关系型数据库会小很多
 
缺点:
  1.多表关联:仅仅支持Left Outer Join
  2.SQL语句支持:查询为主,部分支持
  3.多表原子事务:不支持
  4.多文档原子事务:不支持
  5.16MB文档大小限制,不支持中文排序
  6.服务端Javascript性能欠佳
 
对比关系型数据库

和关系型数据库最大的不同
MongoDB和关系型数据库最大的不同:
 1.传统型数据库:结构化数据,定好了表结构后,每一行的内容必须符合表结构,就是说一列的个数和类型都一样;
2.MongoDB文档型数据库:表中的每个文档都可以有自己独特的结构,即json对象都可以有自己独特的属性和值。
什么时候使用MongoDB
什么时候使用MongoDB
  1.数据量是有亿万级或者需要不断扩容
  2.需要2000-3000以上的读写每秒
  3.新应用,需求会变,数据模型无法确定
  4.需要整合多个外部数据源
  5.系统需要99.999%高可用
  6.系统需要大量的地理位置查询
  7.系统需要提供最小的latency
  8.管理的主要数据对象<10
 
MongoDB数据结构

 
 
MongoDB参考资料
官网帮助手册:https://www.mongodb.com/docs/manual/
 博客:https://www.cnblogs.com/clsn/p/8214194.html
 MongoDB中文社区:https://mongoing.com/
 runoob.com教程:https://www.runoob.com/mongodb/mongodb-tutorial.html
MongoDB部署和访问
官方安装说明:https://www.mongodb.com/docs/manual/installation/
MongoDB支持各种系统安装

二进制安装
官方配置文件说明:https://www.mongodb.com/docs/manual/reference/configuration-options/
创建所需用户和组
useradd mongod
创建mongodb所需目录结构
mkdir -p /mongodb/{conf, data, log}
创建YAML格式的配置文件,早期3.0版本以前是普通文本格式
cat > /mongodb/conf/mongo.conf <<EOF
日志相关
systemLog:
  destination: file
  path: "/mongodb/log/mongodb.log"       日志位置
  logAppend: true                        追加日志
  
数据存储有关
storage:
  dbPath: "/mongodb/data/"               数据路径的位置
进程控制
processManagement:
  fork: true                             后台守护进程
  
网络配置有关
net:
  port: 27017                            端口号,默认不配置端口号,是27017
  bindIp: 0.0.0.0                        监听地址自MongoDB 3.6版本后默认监听在localhost
  
#安全验证有关配置
security:
  authorization: enabled                 是否打开用户名密码验证,默认此项为关掉
EOF
 
cat /mongodb/conf/mongo.conf
systemLog:
  destination: file
  path: "/mongodb/log/mongodb.log"
  logAppend : true
storage :
  dbPath: "/mongodb/data/"
processManagement:
  fork : true
net:
  port: 27017
  bindIp: 0.0.0.0
 
脚本安装
#!/bin/bash
#
#********************************************************************
#Author:            wangxiaochun
#Date:              2021-02-19
#Filename:          install_mongodb.sh
#URL:               http://www.wangxiaochun.com
#Description:       The test script
#Copyright (C):     2021 All rights reserved
#********************************************************************
MONGODB_VERSOIN=rhel80-5.0.4
#MONGODB_VERSOIN=rhel70-5.0.3
#MONGODB_VERSOIN=ubuntu1804-5.0.3
#MONGODB_VERSOIN=ubuntu1804-4.4.4
MONGODB_FILE=mongodb-linux-x86_64-${MONGODB_VERSOIN}.tgz
#MONGODB_FILE=mongodb-linux-x86_64-ubuntu1804-4.4.4.tgz
URL=https://fastdl.mongodb.org/linux/$MONGODB_FILE
MONGODB_DIR=/mongodb
INSTALL_DIR=/usr/local
PORT=27017
MY_IP=`hostname -I|awk '{print $1}'`
. /etc/os-release
color () {
    RES_COL=60
    MOVE_TO_COL="echo -en \\033[${RES_COL}G"
    SETCOLOR_SUCCESS="echo -en \\033[1;32m"
    SETCOLOR_FAILURE="echo -en \\033[1;31m"
    SETCOLOR_WARNING="echo -en \\033[1;33m"
    SETCOLOR_NORMAL="echo -en \E[0m"
    echo -n "$1" && $MOVE_TO_COL
    echo -n "["
    if [ $2 = "success" -o $2 = "0" ] ;then
        ${SETCOLOR_SUCCESS}
        echo -n $"  OK  "    
    elif [ $2 = "failure" -o $2 = "1"  ] ;then 
        ${SETCOLOR_FAILURE}
        echo -n $"FAILED"
    else
        ${SETCOLOR_WARNING}
        echo -n $"WARNING"
    fi
    ${SETCOLOR_NORMAL}
    echo -n "]"
    echo 
}
system_prepare () {
    [ -e $MONGODB_DIR -o -e $INSTALL_DIR/mongodb ] && { color  "MongoDB 数据库已安装!" 1;exit; }
    if  [ $ID = "centos" -o $ID = "rocky" ];then
        rpm -q curl  &> /dev/null || yum install -y -q curl
    elif [ $ID = "ubuntu" ];then
        dpkg -l curl &> /dev/null || apt -y install curl
    else
        color  '不支持当前操作系统!' 1
        exit
    fi
    if [ -e /etc/rc.local ];then
        echo "echo never > /sys/kernel/mm/transparent hugepage/enabled" >> /etc/rc.local
    else
        cat > /etc/rc.local <<EOF
#!/bin/bash
echo never > /sys/kernel/mm/transparent hugepage/enabled
EOF
    fi
    chmod +x /etc/rc.local   
}
mongodb_file_prepare () {
    if [ ! -e $MONGODB_FILE ];then
        curl -O  $URL || { color  "MongoDB 数据库文件下载失败" 1; exit; } 
    fi
}
install_mongodb () {
    id mongod &> /dev/null || useradd -m -s /bin/bash mongod
    tar xf $MONGODB_FILE -C $INSTALL_DIR
    ln -s $INSTALL_DIR/mongodb-linux-x86_64-${MONGODB_VERSOIN} $INSTALL_DIR/mongodb
    #mongod --dbpath $db_dir --bind_ip_all --port $PORT --logpath $db_dir/mongod.log --fork
}
config_mongodb(){
    echo PATH=$INSTALL_DIR/mongodb/bin/:'$PATH' > /etc/profile.d/mongodb.sh
    . /etc/profile.d/mongodb.sh
    mkdir -p $MONGODB_DIR/{conf,data,log}
    cat > $MONGODB_DIR/conf/mongo.conf <<EOF
systemLog:
  destination: file
  path: "$MONGODB_DIR/log/mongodb.log"
  logAppend: true
storage:
  dbPath: "$MONGODB_DIR/data/"
  journal:
    enabled: true
 
processManagement:
  fork: true
net:
  port: 27017
  bindIp: 0.0.0.0
EOF
    chown -R  mongod.mongod $MONGODB_DIR/
    cat > /lib/systemd/system/mongod.service <<EOF
[Unit]
Description=mongodb
After=network.target remote-fs.target nss-lookup.target
[Service]
Type=forking
User=mongod
Group=mongod
ExecStart=$INSTALL_DIR/mongodb/bin/mongod --config $MONGODB_DIR/conf/mongo.conf
ExecReload=/bin/kill -s HUP \$MAINPID
ExecStop=$INSTALL_DIR/bin/mongod --config $MONGODB/conf/mongo.conf --shutdown
PrivateTmp=true
# file size
LimitFSIZE=infinity
# cpu time
LimitCPU=infinity
# virtual memory size
LimitAS=infinity
# open files
LimitNOFILE=64000
# processes/threads
LimitNPROC=64000
# locked memory
LimitMEMLOCK=infinity
# total threads (user+kernel)
TasksMax=infinity
TasksAccounting=false
# Recommended limits for mongod as specified in
# https://docs.mongodb.com/manual/reference/ulimit/#recommended-ulimit-settings
[Install]
WantedBy=multi-user.target
EOF
    systemctl daemon-reload
    systemctl enable --now  mongod &>/dev/null
}
start_mongodb() { 
    systemctl is-active mongod.service &>/dev/null
    if [ $?  -eq 0 ];then  
        echo 
        color "MongoDB 安装完成!" 0
    else
        color "MongoDB 安装失败!" 1
        exit
    fi 
}
system_prepare 
mongodb_file_prepare
install_mongodb
config_mongodb
start_mongodb
 

 
 
MongoDB后台管理shell
如果需要进入mongodb后台管理,可以先打开mongodb装目录的下的 bin目录,然后执行mongo命令文件。
MongoDB Shell是MongoDB自带的交互式Javascript shell,用来对MongoDB进行操作和管理的交互式环境。
mongo是MongoDB早期版本使用的shell工具,将来会被mongosh替代。

 当mongo进入mongoDB后台后,它默认会链接到test数据库,使用db命令可以查看
 
mongodb数据库命令
mongo的help

db.mycoll.help()

mongosh的help

show dbs

use dbname
use命令后直接跟一个名称就可以创建这个名称的数据表(如下截图),不像mysql必须先创建数据表才能use
 
mongosh的安装
官方安装文档:https://www.mongodb.com/docs/mongodb-shell/install/
yum安装或者下载包安装
 mongodb-mongosh-1.1.2.el8.x86_64.rpm

 
然后就可以使用mongosh
 
可视化管理工具
MongoDB Compass是MongoDB官网提供的一个可视化管理工具,可以实现创建数据库、管理集合和文档、运行临时查询、评估和优化查询、性能图表、构建地理查询等功能。
MongoDB Compass官网下载地址:https://www.mongodb.com/products/tools/compass
 
 已经连接成功了
 
 
Python访问MongoDB
yum -y install python3
 
pip3 install pymongo
 

 test_mongodb.py
#!/usr/bin/python3
from pymongo import MongoClient
# 客户端连接
#client = MongoClient(host='127.0.0.1', port=27017) 
client = MongoClient('mongodb://127.0.0.1:27017')
print(client)
# 指定数据库 # Database类
#db = client.test 
db = client['test']
print(db)
# 集合 # Collection类
#users = db['users']
users = db.users
print(users)
for i in range(10):
    user = {'id':i, 'name':'wang' + str(i), 'age':20}
    users.insert_one(user)
for x in users.find():
    print(x)
client.close()
 

 使用show tables查看新增的数据
test> show tables
users
 

 
MongoDB管理
官方帮助手册:https://www.mongodb.com/docs/manual/crud/
库的操作
use可以自动建库,如果库内没有数据,则不使用时会自动删除库
>use test
删除当前所在库
> db.dropDatabase()
{ ok: 1, dropped: 'test' }
可以直接切换至不存在的库
>use testdb1
>db
testdb1
 
可以使用Tab键查看有哪些支持的命令
test> db.drop
db.dropDatabase  db.dropUser      db.dropAllUsers  db.dropRole      db.dropAllRoles
 

集合(表)的操作
灵活的insert
建表方法1:直接创建表
>db.createco1lection ('student ')
建表方法2:当插入一个文档的时候,一个集合就会自动创建。
插入一条数据
db.students.insertOne({
  item: 'canvas',
  qty: 100,
  tags: ['cotton'],
  size: { h: 28, w: 35.5, uom: 'cm' }
});
插入多条数据
db.students.insertMany([
  {
    item: 'journal',
    qty: 25,
    tags: ['blank', 'red'],
    size: { h: 14, w: 21, uom: 'cm' }
  },
  {
    item: 'mat',
    qty: 85,
    tags: ['gray'],
    size: { h: 27.9, w: 35.5, uom: 'cm' }
  },
  {
    item: 'mousepad',
    qty: 25,
    tags: ['gel', 'blue'],
    size: { h: 19, w: 22.85, uom: 'cm' }
  }
]);
 
此时我的数据库中已经有user表了,且表中有只有id,name,age字段,那么此时我插入下面这个记录会成功吗?
db.users.insertOne({
  item: 'canvas',
  qty: 100,
  tags: ['cotton'],
  size: { h: 28, w: 35.5, uom: 'cm' }
});
 
看,插入成功了! mysql这么操作的话是会报错的哦!
 
 
 
 
查看库中的集合列表
show tables
show collections
 

查看集合的信息
db.students.stats()
 

删除集合
db.students.drop()
 

记录(文档操作)
数据录入:
 for (i = 0; i < 10000; i++) {db.student.insertOne({ uid: i, name: "lei" + i, "age": 18, "date": new Date() });}
 
for(i=0;i<10000;i++){db.users.insertOne({uid: i, name: "lei"+i, "age": i, address: "shenzhen"})}
 
for(i=0;i<10000;i++){db.random.insertOne({num: Math.random()* 100000})
 

 

 
查询数据行数
db.student.countDocuments()
 

只显示前三条
db.student.find().limit(3)
 

跳过前面5条记录显示后面的
db.student.find().skip(5)
 

db.student.find({uid:18})
 

查询大于等于18并正序排序的users集合,-1则是倒序
 

 
db.users.find({age: { $gte: 18 }},{ name: 1, address: 1}).limit(5)
 

db.student.deleteOne({uid: 12})
 

用户和权限管理
MongoDB数据库默认是没有用户名及密码的,即无权限访问限制。为了方便数据库的管理和安全,应启用认证和创建数据库用户。
官方帮助手册:https://www.mongodb.com/docs/manual/tutorial/create-users/
用户验证库
关于用户验证库
  1.创建用户时,use所在的库就是此用户的验证库
  2.登录时,必须明确指定验证库才能登录
  3.一个数据库可以成为多个用户的验证库,但一个用户只能使用一个验证库
  4.对于管理员用户,必须在admin下创建,即管理员用的验证库是admin
  5.普通用户的验证库一般是所管理的库
  6.如果直接登录到数据库,不进行use,默认的验证库是test
  7.从3.6版本开始,配置文件中不添加bindIp参数,默认不允许远程登录,只能本地管理员登录。
 
开启用户认证

#方法2,修改配置文件中,加入以下配置
cat >> /mongodb/conf/mongo.conf <<EOF
security:
  authorization: enabled
EOF
systemctl restart mongod
 
用户管理说明
use test
db.createUser(
  {
    user: "myTester",
    pwd:  passwordPrompt(),   // or cleartext password
    roles: [ { role: "readWrite", db: "test" },
             { role: "read", db: "reporting" } ]
  }
)
 

系统内置角色
官方帮助手册:https://www.mongodb.com/docs/manual/reference/built-in-roles/

 
superuser用户
创建超级管理员root(也可以是任意用户名)管理所有数据库(必须use admin再去创建,因为超级用户是存放在admin库中的)
db.createUser ( {user: "superuser", pwd: "123456", roles: [{role: "root", db: "admin"}]})
 

 验证superuser用户是否可以登录
 
普通用户
创建一个普通用户myTester,对test数据库有读写权限,对test2只有读的权限
db.createUser(
  {
    user: "myTester",
    pwd:  passwordPrompt(), 
    roles: [ { role: "readWrite", db: "test" },
             { role: "read", db: "test2" } ]
  }
)
 

 
 验证myTester用户的登录
 
 验证用户也可以不用去登录判断该用户是否生效,可以直接使用db.auth(‘用户名’,‘密码’)命令验证,返回ok:1则为用户创建成功。
db.auth('myTester', '123456')
 

验证myTester是否对test2有写权限
 
查看所有用户信息
db.system.users.find().pretty()
 
要使用超级管理员在admin库中查看
test> use admin 
switched to db admin
admin> db.system.users.find().pretty()
[
  {
    _id: 'admin.superuser',
    userId: UUID("61b779dd-f242-4f2c-af0c-ffa29381023e"),
    user: 'superuser',
    db: 'admin',
    credentials: {
     ......
    },
    roles: [ { role: 'root', db: 'admin' } ]
  },
  {
    _id: 'test.myTester',
    userId: UUID("59dbc2ec-a171-4666-9f4a-ab8b49f97b04"),
    user: 'myTester',
    db: 'test',
    credentials: {
      ......
    },
    roles: [
      { role: 'read', db: 'test2' },
      { role: 'readWrite', db: 'test' }
    ]
  }
]
admin>
 
MongoDB复制集
MongDB像MySQL一样,支持类似的主从复制架构,但无法实现自动故障转移,所以官方推荐使用复制集。
MongoDB复制集是将数据同步在多个服务器的过程,复制集提供了数据的冗余备份,并在多个服务器上存储数据副本,保证数据的安全性。
复制集还允许从硬件故障和服务中断中恢复数据。当故障时,会自动选举新master节点实现集群的高可用。
官方帮助手册:https://www.mongodb.com/docs/manual/replication/
复制集架构
MongoDB的复制至少需要两个节点。其中一个是主节点,负责处理客户端请求,主节点接收所有写入操作。其余的都是从节点,负责复制主节点上的数据。
MongoDB各个节点常见的搭配方式为:一主一从、一主两从此方式最多。
主节点记录在其上的所有操作oplog(操作日志),从节点定期轮询主节点获取这些操作,然后对自己的数据副本执行这些操作,从而保证从节点的数据与主节点一致。
客户端写入数据到主节点时,主节点与从节点进行数据交互保障数据的一致性。

复制集特征:
  1.N个奇数节点的集群
  2.基于选举机制,任何节点可作为主节点
  3.所有写入操作都在主节点上,所以增加节点不会提高系统写性能,可以提升读性能
  4.主节点故障时,会自动选举出新节点代替,自动故障转移
 
复制集实现
复制集要求三个以上的MongoDB节点
我有三台机器154、155、156,都有安装好了MongoDB
 
1.配置mongo.conf文件
在三台主机的配置文件中分别加上以下配置
 vim /mongodb/conf/mongo.conf
replication:
  replSetName: myrepl
 
示例
systemLog:
  destination: file
  path: "/mongodb/log/mongodb.log"
  logAppend: true
storage:
  dbPath: "/mongodb/data/"
  journal:
    enabled: true
processManagement:
  fork: true
net:
  port: 27017
  bindIp: 0.0.0.0
#security:
#  authorization: enabled
replication:
  replSetName: myrepl   制定复制集名称,所有复制集成员此名称要一致
 
2.初始化设置,
以下配置在三台主机中任意一台执行
config = { _id: 'myrepl', members: [
	{_id: 0, host: '192.168.10.154:27017'},
	{_id: 1, host: '192.168.10.155:27017'},
	{_id: 2, host: '192.168.10.156:27017'}]
	}
 
3.执行rs.initiate(初始化设置的函数名)
rs.initiate(config)
 
我在154这台机器上执行的
 
 
 此时155和156上则显示SECONDARY
 
查看复制集状态

myrepl:PRIMARY> rs.isMaster()
{
	"topologyVersion" : {
		"processId" : ObjectId("66a78b7916704ef3521b7b5c"),
		"counter" : NumberLong(10)
	},
	"hosts" : [
		"192.168.10.154:27017",
		"192.168.10.155:27017",
		"192.168.10.156:27017"
	],
	"setName" : "myrepl",
	"setVersion" : 1,
	"ismaster" : true,
	"secondary" : false,
	"primary" : "192.168.10.154:27017",
	"me" : "192.168.10.154:27017",
	"electionId" : ObjectId("7fffffff0000000000000002"),
	"lastWrite" : {
		"opTime" : {
			"ts" : Timestamp(1722257856, 1),
			"t" : NumberLong(2)
		},
		"lastWriteDate" : ISODate("2024-07-29T12:57:36Z"),
		"majorityOpTime" : {
			"ts" : Timestamp(1722257856, 1),
			"t" : NumberLong(2)
		},
		"majorityWriteDate" : ISODate("2024-07-29T12:57:36Z")
	},
	"maxBsonObjectSize" : 16777216,
	"maxMessageSizeBytes" : 48000000,
	"maxWriteBatchSize" : 100000,
	"localTime" : ISODate("2024-07-29T12:57:40.021Z"),
	"logicalSessionTimeoutMinutes" : 30,
	"connectionId" : 1,
	"minWireVersion" : 0,
	"maxWireVersion" : 13,
	"readOnly" : false,
	"ok" : 1,
	"$clusterTime" : {
		"clusterTime" : Timestamp(1722257856, 1),
		"signature" : {
			"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
			"keyId" : NumberLong(0)
		}
	},
	"operationTime" : Timestamp(1722257856, 1)
}
myrepl:PRIMARY> 
 
slaveOk()
SECONDARY节点默认不提供访问,需要执行slaveOK()来打开访问设置
 
 
 rs.slaveOk()将来会被rs.secondaryOk()取代
 
 
secondary节点只能读,不能写

添加和删除节点
删除一个节点
rs.remove ("ip: port")
新增从节点
rs.add ("ip: port")
#新增仲裁节点
rs.addArb ("ip: port")
 
示例
添加一个节点
myrepl:PRIMARY> rs.add ("192.168.10.157: 27017")
删除一个节点
myrepl:PRIMARY> rs.remove ("192.168.10.157: 27017")
{ "ok": 1 }
添加仲裁节点
myrepl:PRIMARY> rs.addArb ("192.168.10.158:27017")
 
myrepl:SECONDARY> db.isMaster()
{
	"hosts" : [
		"192.168.10.154:27017",
		"192.168.10.155:27017",
		"192.168.10.156:27017"
	],
	"arbiters" : [
	    "192.168.10.158:27017"
	],
}
 
复制集角色说明
主要角色
主节点[Primary]
接收所有的写请求,然后把修改同步到所有Secondary。一个Replica Set只能有一个Primary节点,当Primary挂掉后,其他Secondary或者Arbiter节点会重新选举出来一个主节点。默认读请求也是发到Primary节点处理的,如果需要转发到Secondary,需要在客户端修改一下连接配置。
副本节点[Secondary]
与主节点保持同样的数据集。当主节点挂掉的时候,可以参与选举出新主节点。
仲裁者[Arbiter]
不保存数据,不参与选主,只进行选主投票。使用Arbiter可以减轻数据存储的硬件需求,Arbiter跑起来几乎没什么大的硬件资源需求,在生产环境下它和其他数据节点不要部署在同一台机器上。实际生产环境当前不推存使用Arbiter节点类型
MongoDB使用Raft选举机制,而MySQL MGR 用的是Paxos,而Raft本质是Paxos的变种
 注意,一个自动failover的Replica Set节点数必须为奇数,目的是选主投票的时候要有一个大多数才能进行选主决策。
Primary选举实现
复制集通过replSetInitiate命令(或mongo shell的rs.initiate())进行初始化,初始化后各个成员间开始发送心跳消息,并发起Primary选举操作,获得大多数成员投票支持的节点,会成为Primary,其余节点成为Secondary。
选举实现
  1.具有投票权的节点之间两两互相发送心跳
  2.当5次心跳未收到时,判断为节点失联
  3.如果失联的是主节点,从节点会发起选举,选出新的主节点
  4·如果失联的是从节点则不会产生新的选举
  5.选举基于RAFT一致性算法实现,选举成功的必要条件是大多数投票节点存活
  6.复制集中最多可以有50个节点,但具有投票权的节点最多7个,且为奇数个投票成员
 
大多数的定义
 假设复制集内投票成员(后续介绍)数量为N,则大多数为N/2+1,当复制集内存活成员数量不足大多数时,整个复制集将无法选举出Primary,复制集将无法提供写服务,处于只读状态。
 
 通常建议将复制集成员数量设置为奇数,从上表可以看出3个节点和4个节点的复制集都只能容忍1个节点失效,从服务可用性的角度看,其效果是一样的。(但无疑4个节点能提供更可靠的数据存储)
被选举为主节点的节点必须:
  1.能够与多数节点建立连接
  2.具有较新的oplog
  3.具有较高的优先级(如果有配置)
 
其他角色

rs.conf()查看优先级

MongoDB备份恢复
虽然有复制集的高可用性保证,数据丢失的可能很低,但仍然需要备份。
备份的目的:
  1.防止硬件故障引起的数据丢失
  2.防止人为错误误删数据
  3.时间回溯
  4.监管要求
 
备份恢复的两个工具
1.mongoexport/mongoimport
mongoexport/mongoimport可以实现逻辑备份,类似于mysqldump,可以导出json或csv格式文件
应用场景总结
  1.异构平台迁移,比如:MySQL和MongoDB
  2.同平台跨大版本的MongoDB数据导出导入:比如mongodb 2 ----> mongodb 3
 
2.mongodump/mongorestore
物理备份,日常备份恢复时使用,导出的二进制文件。
mongodump能够在Mongodb运行时进行备份,它的工作原理是对运行的Mongodb做查询,然后将所有查到的文档写入磁盘,但是存在的问题时使用mongodump产生的备份不一定是数据库的实时快照,如果我们在备份时对数据库进行了写入操作,则备份出来的文件可能不完全和Mongodb实时数据相等。另外在备份时可能会对其它客户端性能产生不利的影响。
使用mongodump备份最灵活,但速度上也是最慢的
mongodump出来的数据不能表示某个时间点,只是某个时间段
 
两种工具的对比
mongoexport/mongoimport导入/导出的是JSON格式
 而mongodump/mongorestore导入/导出的是BSON格式。
JSON可读性强但体积较大,BSON则是二进制文件,体积小但对人类几乎没有可读性。
在一些mongodb版本之间,BSON格式可能会随版本不同而有所不同,所以不同版本之间用mongodump/mongorestore可能不会成功,具体要看版本之间的兼容性。
当无法使用BSON进行跨版本的数据迁移的时候,使用JSON格式即mongoexport/mongoimport是一个可选项。
跨版本的mongodump/mongorestore并不推荐,实在要做请先检查文档看两个版本是否兼容。
 JSON虽然具有较好的跨版本通用性,但其只保留了数据部分,不保留索引,账户等其他基础信息。
mongoexport/mongoimport
导出工具 mongoexport
此工具只能针对单表,不支持整库的表导出
官方帮助手册:https://www.mongodb.com/docs/database-tools/mongoexport/
下载链接:https://www.mongodb.com/try/download/database-tools
我下载的是rpm包
yum -y install  mongodb-database-tools-rhel80-x86_64-100.5.1.rpm
 
可以使用一下命令,查看导出导出工具
rpm -ql mongodb-database-tools
 

 mongoexport具体用法使用"mongoexport --help"查看帮助,部分参数使用如下所示:
[root@rocky ~]# mongoexport --help
参数说明:
-h   指明数据库宿主机的IP
-u   指明数据库的用户名
-p   指明数据库的密码
-d   指明数据库的名字
-c   指明co1lection的名字
-f   指明要导出那些列
-o   指明到要导出的文件名
-q   指明导出数据的过滤条件
--type=Csv或--csv   指定导出为csv格式,默认json格式
--authenticationDatabase<验证库>   指定验证库
 
导出json格式示例
目前在test库中有一张users表,表中有一万条记录
 
mongoexport -d test -c users -o /backup/users.json
 

 使用wc -l 查看下导出的文件有多少行
 
 
导出csv格式示例
导出test库中userStore表的一万条记录为csv格式
 
mongoexport -d test -c userStore --type=csv -f uid,name,age,address -o /backup/users.csv
 
导出成功了
 
 查看一下导出的users.csv文件的样子
 
导入工具mongoimport
官方帮助手册:https://www.mongodb.com/docs/database-tools/mongoimport/
[root@rocky ~]# mongoimport --help
Usage:
  mongoimport <options> <connection-string> <file> 
Import CSV, TSV or JSON data into MongoDB. If no file is provided, mongoimport reads from stdin.
Connection strings must begin with mongodb:// or mongodb+srv://.
See http://docs.mongodb.com/database-tools/mongoimport/ for more information.
参数说明:
-h      指明数据库宿主机的IP
-u      指明数据库的用户名
-p      指明数据库的密码
-d      指明数据库的名字
-c      指明co1lection的名字-f#指明要导入那些列
--type=csv   指定导入cSv格式文件,默认json格式
-j,--numInsertionworkers=<number>    同时插入的数量,默认为
--headerline   指明第一行是列名,不需要导入
 
导入示例
1.删除users表
 
 2.将/backup/users.json 数据导入到userStore表中,userStore表不存在会自动创建。
mongoimport -d test -c userStore /backup/users.json 
 

 
 


















