mongo

mongo

第一章 mongo简介

1.关系型与非关系型

NoSQL not only sql
NoSQL,指的是非关系型的数据库。
NoSQL有时也称作Not Only SQL的缩写
是对不同于传统的关系型数据库的数据库管理系统的统称。
对NoSQL最普遍的解释是”非关联型的”,强调Key-Value Stores和文档数据库的优点,而不是单纯的RDBMS。
NoSQL用于超大规模数据的存储。
这些类型的数据存储不需要固定的模式,无需多余操作就可以横向扩展。

今天我们可以通过第三方平台可以很容易的访问和抓取数据。
用户的个人信息,社交网络,地理位置,用户生成的数据和用户操作日志已经成倍的增加。
我们如果要对这些用户数据进行挖掘,那SQL数据库已经不适合这些应用了
NoSQL数据库的发展也却能很好的处理这些大的数据。

2.mongo和mysql数据对比

mongo数据库方面 如果没有这个库这个表 也可以直接插入数据 会帮你自动创建

没有的字符也可以直接插入 自动帮你创建

mysql 	mongo 
库		库
表		集合
字段	key:value
行		文档 

name  		age  job  
oldzhang 	28   it 
xiaozhang	28	 it
xiaofei		18 	 student  SZ 

{name:'oldzhang',age:'28',job:'it'},
{name:'xiaozhang',age:'28',job:'it'},
{name:'xiaozhang',age:'28',job:'it',host:'SZ'}

3.MongoDB特点

  • 高性能:
    Mongodb提供高性能的数据持久性
    尤其是支持嵌入式数据模型减少数据库系统上的I/O操作
    索引支持能快的查询,并且可以包括来嵌入式文档和数组中的键
  • 丰富的语言查询:
    Mongodb支持丰富的查询语言来支持读写操作(CRUD)以及数据汇总,文本搜索和地理空间索引
  • 高可用性:
    Mongodb的复制工具,成为副本集,提供自动故障转移和数据冗余
  • 水平可扩展性:
    Mongodb提供了可扩展性,作为其核心功能的一部分,分片是将数据分,在一组计算机上
  • 支持多种存储引擎:
    WiredTiger存储引擎和、MMAPv1存储引擎和InMemory存储引擎

4.mongo应用场景

1.游戏场景,使用 MongoDB 存储游戏用户信息,用户的装备、积分等直接以内嵌文档的形式存储,方便查询、更新

2.物流场景,使用 MongoDB 存储订单信息,订单状态在运送过程中会不断更新,以 MongoDB 内嵌数组的形式来存储,一次查询就能将订单所有的变更读取出来。

3.社交场景,使用 MongoDB 存储存储用户信息,以及用户发表的朋友圈信息,通过地理位置索引实现附近的人、地点等功能

4.物联网场景,使用 MongoDB 存储所有接入的智能设备信息,以及设备汇报的日志信息,并对这些信息进行多维度的分析

5.视频直播,使用 MongoDB 存储用户信息、礼物信息等,用户评论

6.电商场景,使用 MongoDB
商城上衣和裤子两种商品,除了有共同属性,如产地、价格、材质、颜色等外,还有各自有不同的属性集,如上衣的独有属性是肩宽、胸围、袖长等,裤子的独有属性是臀围、脚口和裤长等

第二章 mongo安装

端口:27017

1.规划目录

#软件所在目录
/opt/mongodb
#单节点目录
/opt/mongo_27017/{conf,log,pid}
#数据目录
/data/mongo_27017

2.下载并解压

上传下载好的包 官网下载4.0版
[root@db01 ~]# yum install libcurl openssl -y
[root@db01 ~]# tar xf mongodb-linux-x86_64-rhel70-4.0.14.tgz -C /opt/

[root@db01 ~]# ln -s mongodb-linux-x86_64-rhel70-4.0.14 mongodb

[root@db01 ~]# mkdir -p /opt/mongo_27017/{conf,log,pid}
[root@db01 ~]# mv /data /data_bak【之前有东西就先挪走】
[root@db01 ~]# mkdir -p /data/mongo_27017

3.配置启动mongo

[root@db01 ~]# cat >/opt/mongo_27017/conf/mongodb.conf<<EOF
##系统日志有关
systemLog:
  destination: file   
  logAppend: true                          ##日志以追加模式记录
  path: /opt/mongo_27017/log/mongodb.log   ##日志位置

##数据存储有关  
storage:
  journal:
    enabled: true
  dbPath: /data/mongo_27017    ##数据路径的位置
  directoryPerDB: true
  wiredTiger:
     engineConfig:
        cacheSizeGB: 1
        directoryForIndexes: true
     collectionConfig:
        blockCompressor: zlib
     indexConfig:
        prefixCompression: true

##进程控制 
processManagement:
  fork: true           ##后台守护进程
  pidFilePath: /opt/mongo_27017/pid/mongod.pid ##pid文件的位置,一般不用配置,可以去掉这行,自动生成到data中

##网络配置有关  
net:
  port: 27017                  ##端口号,默认不配置端口号,是27017
  bindIp: 127.0.0.1,10.0.0.51  ##监听地址
EOF 


# 启动
[root@db01 ~]# /opt/mongodb/bin/mongod -f /opt/mongo_27017/conf/mongodb.conf

[root@db01 ~]# netstat -lntup|grep 27017
 
# 写入环境变量
[root@db01 ~]# echo 'export PATH=/opt/mongodb/bin:$PATH' >> /etc/profile
[root@db01 ~]# source /etc/profile
[root@db01 ~]# mongo

4.关闭mongo

# 方法1:
使用localhost登录
[root@db01 ~]# mongo localhost:27017
[root@db01 ~]# use admin
[root@db01 ~]# db.shutdownServer()

# 方法2:
[root@db01 ~]# mongod -f /opt/mongo_27017/conf/mongodb.conf --shutdown

第三章 优化告警

1.访问控制

WARNING: Access control is not enabled for the database.
Read and write access to data and configuration is unrestricted.
【解决方法】:
开启安全认证功能

2.以root用户运行

WARNING: You are running this process as the root user, which is not recommended.

【解决方法1】:创建普通用并切换启动
[root@db01 ~]# mongod -f /opt/mongo_27017/conf/mongodb.conf --shutdown
[root@db01 ~]# useradd mongo
[root@db01 ~]# echo '123456'|passwd --stdin mongo
[root@db01 ~]# chown -R mongo:mongo /opt/
[root@db01 ~]# chown -R mongo:mongo /data/
[root@db01 ~]# su - mongo
[root@db01 ~]# mongod -f /opt/mongo_27017/conf/mongodb.conf
[root@db01 ~]# mongo


【解决方法2】:创建systemcd启动文件
[root@db01 ~]# cat >/lib/systemd/system/mongod.service<<EOF
[Unit]
Description=MongoDB Database Server
Documentation=https://docs.mongodb.org/manual
After=network.target

[Service]
User=mongod
Group=mongod
Environment="OPTIONS=-f /opt/mongo_27017/conf/mongodb.conf"
ExecStart=/opt/mongodb/bin/mongod \$OPTIONS
ExecStartPre=/usr/bin/chown -R mongod:mongod /opt/mongo_27017
ExecStartPre=/usr/bin/chown -R mongod:mongod /data/mongo_27017
PermissionsStartOnly=true
PIDFile=/opt/mongo_27017/pid/mongod.pid
Type=forking
# 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 for mongod as specified in
# http://docs.mongodb.org/manual/reference/ulimit/#recommended-settings

[Install]
WantedBy=multi-user.target
EOF

[root@db01 ~]# useradd mongod -M -s /sbin/nologin
[root@db01 ~]# systemctl daemon-reload
[root@db01 ~]# systemctl start mongod

3.关闭大内存页技术

WARNING: /sys/kernel/mm/transparent_hugepage/enabled is 'always'.
We suggest setting it to 'never'
WARNING: /sys/kernel/mm/transparent_hugepage/defrag is 'always'.
We suggest setting it to 'never'

【解决方法】:
临时解决:
[root@db01 ~]# echo "never" >/sys/kernel/mm/transparent_hugepage/enabled
[root@db01 ~]# echo "never" >/sys/kernel/mm/transparent_hugepage/defrag
写入开机自启动:
[root@db01 ~]# chmod +x /etc/rc.d/rc.local
[root@db01 ~]# echo "never" >/sys/kernel/mm/transparent_hugepage/enabled
[root@db01 ~]# echo "never" >/sys/kernel/mm/transparent_hugepage/defrag
验证:
[root@db01 ~]# mongod -f /opt/mongo_27017/conf/mongodb.conf --shutdown
[root@db01 ~]# mongod -f /opt/mongo_27017/conf/mongodb.conf 
[root@db01 ~]# mongo 

4.解决rlimits太低

WARNING: soft rlimits too low. rlimits set to 31771 processes, 65535 files. Number of processes should be at least 32767.5 : 0.5 times number of files.
【解决方法1】:
[root@db01 ~]# vim /etc/profile
ulimit -f unlimited
ulimit -t unlimited
ulimit -v unlimited
ulimit -n 64000
ulimit -m unlimited
ulimit -u 64000

生效配置:
[root@db01 ~]# source /etc/profile
验证:
[root@db01 ~]#mongod -f /opt/mongo_27017/conf/mongodb.conf --shutdown
[root@db01 ~]#mongod -f /opt/mongo_27017/conf/mongodb.conf 
[root@db01 ~]#mongo 

【解决方法2】:创建systemcd启动文件启动

一般使用创建systemctl启动文件 这个可以同时解决2和4的问题

第四章 mongo命令

1.查看指令

test:登录时默认存在的库 
admin库:系统预留库,MongoDB系统管理库
local库:本地预留库,存储关键日志
config库:MongoDB配置信息库

> show databases/show dbs 【查不到test库 是因为里面没数据】
admin   0.000GB
config  0.000GB
local   0.000GB

> show tables/show collections
admin   0.000GB
config  0.000GB
local   0.000GB

> use admin
> db/select database()

2.插入命令

# 1.插入单条【没有这个表 会自动帮你创建】
db.user_info.insert({"name":"zhangya","age":27,"ad":"北京市朝阳区"})
db.user_info.insert({"name":"zhangya","age":27,"ad":"北京市朝阳区"})
db.user_info.insert({"name":"yazhang","age":28,"ad":"北京市朝阳区"})
db.user_info.insert({"name":"xiaozhang","age":28,"ad":"北京市朝阳区"})
db.user_info.insert({"name":"xiaozhang","age":28,"ad":"北京市朝阳区","sex":"boy"})
WriteResult({ "nInserted" : 1 })

# 2.插入多条
db.inventory.insertMany( [
    { "item": "journal", "qty": 25, "size": { "h": 14, "w": 21, "uom": "cm" }, "status": "A" },
    { "item": "notebook", "qty": 50, "size": { "h": 8.5, "w": 11, "uom": "in" }, "status": "A" },
    { "item": "paper", "qty": 100, "size": { "h": 8.5, "w": 11, "uom": "in" }, "status": "D" },
    { "item": "planner", "qty": 75, "size": { "h": 22.85, "w": 30, "uom": "cm" }, "status": "D" },
    { "item": "postcard", "qty": 45, "size": { "h": 10, "w": 15.25, "uom": "cm" }, "status": "A" }
]);

3.查询命令

# 1.查询一条
db.user_info.findOne()
{
	"_id" : ObjectId("5e01b754926392b74472fa8d"),
	"name" : "sata",
	"age" : "19"
}


# 2.查询所有
db.user_info.find()
{ "_id" : ObjectId("5e01b754926392b74472fa8d"), "name" : "sata", "age" : "19" }
{ "_id" : ObjectId("5e01b768926392b74472fa8e"), "name" : "sata", "age" : "19", "ad" : "北京" }
{ "_id" : ObjectId("5e01b941926392b74472fa8f"), "name" : "jiu", "age" : 69, "ad" : "北京" }
{ "_id" : ObjectId("5e01f326926392b74472fa90"), "name" : "zhangya", "age" : 27, "ad" : "北京市朝阳区" }
{ "_id" : ObjectId("5e01f326926392b74472fa91"), "name" : "zhangya", "age" : 27, "ad" : "北京市朝阳区" }
{ "_id" : ObjectId("5e01f326926392b74472fa92"), "name" : "yazhang", "age" : 28, "ad" : "北京市朝阳区" }
{ "_id" : ObjectId("5e01f326926392b74472fa93"), "name" : "xiaozhang", "age" : 28, "ad" : "北京市朝阳区" }
{ "_id" : ObjectId("5e01f328926392b74472fa94"), "name" : "xiaozhang", "age" : 28, "ad" : "北京市朝阳区", "sex" : "boy" }


# 3.查询符合条件
db.user_info.find({"age":28})
{ "_id" : ObjectId("5e01f326926392b74472fa92"), "name" : "yazhang", "age" : 28, "ad" : "北京市朝阳区" }
{ "_id" : ObjectId("5e01f326926392b74472fa93"), "name" : "xiaozhang", "age" : 28, "ad" : "北京市朝阳区" }
{ "_id" : ObjectId("5e01f328926392b74472fa94"), "name" : "xiaozhang", "age" : 28, "ad" : "北京市朝阳区", "sex" : "boy" }

    
# 4.查询嵌套的条件
db.inventory.find({"size.uom":"in"})

db.inventory.find( 
	{ 
		"size.uom": "in" 
	} 
)
{ "_id" : ObjectId("5e01f35e926392b74472fa96"), "item" : "notebook", "qty" : 50, "size" : { "h" : 8.5, "w" : 11, "uom" : "in" }, "status" : "A" }
{ "_id" : ObjectId("5e01f35e926392b74472fa97"), "item" : "paper", "qty" : 100, "size" : { "h" : 8.5, "w" : 11, "uom" : "in" }, "status" : "D" }

    
# 5.逻辑查询:and 【默认and不用写】
db.inventory.find({"size.uom":"in"})

db.inventory.find( 
	{ 
		"size.uom": "cm" ,
		"status" : "A"
	} 
)
{ "_id" : ObjectId("5e01f35e926392b74472fa96"), "item" : "notebook", "qty" : 50, "size" : { "h" : 8.5, "w" : 11, "uom" : "in" }, "status" : "A" }
{ "_id" : ObjectId("5e01f35e926392b74472fa97"), "item" : "paper", "qty" : 100, "size" : { "h" : 8.5, "w" : 11, "uom" : "in" }, "status" : "D" }
> db.inventory.find({"size.uom":"cm","status":"A"})
{ "_id" : ObjectId("5e01f35e926392b74472fa95"), "item" : "journal", "qty" : 25, "size" : { "h" : 14, "w" : 21, "uom" : "cm" }, "status" : "A" }
{ "_id" : ObjectId("5e01f35e926392b74472fa99"), "item" : "postcard", "qty" : 45, "size" : { "h" : 10, "w" : 15.25, "uom" : "cm" }, "status" : "A" }


# 6.逻辑查询:or
db.inventory.find(
	{
		$or:[
				{status:"D"},
				{qty:{$lt:30}}
			]
	}
)
{ "_id" : ObjectId("5e01f35e926392b74472fa95"), "item" : "journal", "qty" : 25, "size" : { "h" : 14, "w" : 21, "uom" : "cm" }, "status" : "A" }
{ "_id" : ObjectId("5e01f35e926392b74472fa97"), "item" : "paper", "qty" : 100, "size" : { "h" : 8.5, "w" : 11, "uom" : "in" }, "status" : "D" }
{ "_id" : ObjectId("5e01f35e926392b74472fa98"), "item" : "planner", "qty" : 75, "size" : { "h" : 22.85, "w" : 30, "uom" : "cm" }, "status" : "D" }


# 7.逻辑查询+或+and+正则表达式
db.inventory.find({status:"A",$or:[{qty:{$lt:30}},{item:/^p/}]})

db.inventory.find( 
	{
		status: "A",
		$or: [ 
				{ qty: { $lt: 30 } }, 
				{ item: /^p/ } 
			 ]
	} 
)
{ "_id" : ObjectId("5e01f35e926392b74472fa95"), "item" : "journal", "qty" : 25, "size" : { "h" : 14, "w" : 21, "uom" : "cm" }, "status" : "A" }
{ "_id" : ObjectId("5e01f35e926392b74472fa99"), "item" : "postcard", "qty" : 45, "size" : { "h" : 10, "w" : 15.25, "uom" : "cm" }, "status" : "A" }


# 8.每页显示50条记录:
DBQuery.shellBatchSize=50; 


# 9.以标准的json格式显示数据
> db.log.find({uid:999}).pretty()
{
    "_id" : ObjectId("5cc516e60d13144c89dead33"),
    "uid" : 999,
    "name" : "mongodb",
    "age" : 6,
    "date" : ISODate("2019-04-28T02:58:46.109Z")
}

4.更新数据

# 1.更改匹配条件的单条数据
db.inventory.find({ "item" : "paper" })
db.inventory.updateOne{ "item" : "paper" },{$set: {  "size.uom" : "cm",  "status" : "P" }})
db.inventory.updateOne(
    { "item" : "paper" },
    {
      $set: {  
				"size.uom" : "cm",  
				"status" : "P" 
			}
    }
)

# 2.更改匹配条件的多条数据
db.inventory.find({ "qty" : { $lt: 50 } })
db.inventory.updateMany(
    { "qty" : { $lt: 50 } },
    {
       $set: 
			{ 
				"size.uom" : "mm", 
				"status": "P" 
			}
    }
)

# 3.添加字段
db.user_info.find({ "age" : 27})
db.user_info.updateMany(
    { "age" : 27},
    {
       $set: 
			{ 
				"pet" : "cat"
			}
    }
)

5.索引

# 1.查看执行计划
db.user_info.find({"age":{ $lt: 30 }})
db.user_info.find({"age":{ $lt: 30 }}).explain()

# 2.创建索引
db.user_info.createIndex({ age: 1 },{background: true})

# 3.查看索引
db.user_info.getIndexes()

# 4.再次查看执行计划
db.user_info.find({"age":{ $lt: 30 }}).explain()

关键词
"stage" : "IXSCAN"
"indexName" : "age_1"

# 5.删除索引
db.user_info.dropIndex("age_1")

# 其他索引类型
COLLSCAN – Collection scan
IXSCAN – Scan of data in index keys
FETCH – Retrieving documents
SHARD_MERGE – Merging results from shards
SORT – Explicit sort rather than using index orde

6.删除

# 1.先查找需要删除的数据
db.inventory.find({"status":"P"})
{ "_id" : ObjectId("5e01f35e926392b74472fa95"), "item" : "journal", "qty" : 25, "size" : { "h" : 14, "w" : 21, "uom" : "mm" }, "status" : "P" }
{ "_id" : ObjectId("5e01f35e926392b74472fa97"), "item" : "paper", "qty" : 100, "size" : { "h" : 8.5, "w" : 11, "uom" : "cm" }, "status" : "P" }
{ "_id" : ObjectId("5e01f35e926392b74472fa99"), "item" : "postcard", "qty" : 45, "size" : { "h" : 10, "w" : 15.25, "uom" : "mm" }, "status" : "P" }


# 2.删除单条
db.inventory.deleteOne({"status":"P"})
db.inventory.find({"status":"P"})
{ "_id" : ObjectId("5e01f35e926392b74472fa97"), "item" : "paper", "qty" : 100, "size" : { "h" : 8.5, "w" : 11, "uom" : "cm" }, "status" : "P" }
{ "_id" : ObjectId("5e01f35e926392b74472fa99"), "item" : "postcard", "qty" : 45, "size" : { "h" : 10, "w" : 15.25, "uom" : "mm" }, "status" : "P" }


# 3.删除多个
db.inventory.deleteMany({"status":"P"})
db.inventory.find({"status":"P"})


# 4.删除索引
db.user_info.dropIndex("age_1")


# 5.删除集合
show dbs
db 
show tables
db.inventory.drop()


# 6.删除库
show dbs
db 
db.dropDatabase()

第五章 mongostat命令解释

mongo工具:

mongod			#启动命令
mongo			#登录命令         
mongodump   	#备份导出,全备压缩
mongorestore 	#恢复
mongoexport   	#备份,数据可读json
mongoimport 	#恢复
mongostat		#查看mongo运行状态
mongotop		#查看mongo运行状态
mongos  		#集群分片命令

mongostat

各字段解释说明:
insert/s : 官方解释是每秒插入数据库的对象数量,如果是slave,则数值前有*,则表示复制集操作
query/s  : 每秒的查询操作次数
update/s : 每秒的更新操作次数
delete/s : 每秒的删除操作次数
getmore/s: 每秒查询cursor(游标)时的getmore操作数
command  : 每秒执行的命令数,在主从系统中会显示两个值(例如 3|0),分表代表 本地|复制 命令

#注: 一秒内执行的命令数比如批量插入,只认为是一条命令(所以意义应该不大)

dirty    : 仅仅针对WiredTiger引擎,官网解释是脏数据字节的缓存百分比
used     :仅仅针对WiredTiger引擎,官网解释是正在使用中的缓存百分比
flushes  :
For WiredTiger引擎:指checkpoint的触发次数在一个轮询间隔期间
For MMAPv1引擎:每秒执行fsync将数据写入硬盘的次数

#注:一般都是0,间断性会是1, 通过计算两个1之间的间隔时间,可以大致了解多长时间flush一次。flush开销是很大的,如果频繁的flush,可能就要找找原因了

vsize: 虚拟内存使用量,单位MB (这是 在mongostat 最后一次调用的总数据)
res:    物理内存使用量,单位MB (这是 在mongostat 最后一次调用的总数据)

#注:这个和你用top看到的一样, vsize一般不会有大的变动, res会慢慢的上升,如果res经常突然下降,去查查是否有别的程序狂吃内存。

qr: 客户端等待从MongoDB实例读数据的队列长度
qw:客户端等待从MongoDB实例写入数据的队列长度
ar: 执行读操作的活跃客户端数量
aw: 执行写操作的活客户端数量
注:如果这两个数值很大,那么就是DB被堵住了,DB的处理速度不及请求速度。看看是否有开销很大的慢查询。如果查询一切正常,确实是负载很大,就需要加机器了
netIn:MongoDB实例的网络进流量
netOut:MongoDB实例的网络出流量

#注:此两项字段表名网络带宽压力,一般情况下,不会成为瓶颈

conn: 打开连接的总数,是qr,qw,ar,aw的总和

#注:MongoDB为每一个连接创建一个线程,线程的创建与释放也会有开销,所以尽量要适当配置连接数的启动参数,maxIncomingConnections,阿里工程师建议在5000以下,基本满足多数场景

第六章 mongo权限认证

1.与用户相关的命令

db.auth() #将用户验证到数据库。
db.changeUserPassword() #更改现有用户的密码。
db.createUser() #创建一个新用户。
db.dropUser() #删除单个用户。
db.dropAllUsers() #删除与数据库关联的所有用户。
db.getUser() #返回有关指定用户的信息。
db.getUsers() #返回有关与数据库关联的所有用户的信息。
db.grantRolesToUser() #授予用户角色及其特权。
db.removeUser() #已过时。从数据库中删除用户。
db.revokeRolesFromUser() #从用户中删除角色。
db.updateUser() #更新用户数据。

2.创建管理用户

mongo 10.0.0.51:27017
use admin 
db.createUser(
	{
		user: "admin",
		pwd: "123456",
		roles:[ 
				{ 
					role: "root", 
					db:"admin"
				}
			  ]
	}	
)

db.getUsers()

3.配置文件添加权限认证参数

[root@db01 ~]# vim /opt/mongo_27017/conf/mongodb.conf
security:     
  authorization: enabled

4.重启mongo

[root@db01 ~]# systemctl stop mongod
[root@db01 ~]# systemctl start mongod

5.使用admin用户登录

[root@db01 ~]# mongo 10.0.0.51:27017 -uadmin -p --authenticationDatabase admin
MongoDB shell version v4.0.14
Enter password:

6.创建其他用户

[root@db01 ~]# mongo 10.0.0.51:27017 -uadmin -p --authenticationDatabase admin
MongoDB shell version v4.0.14
Enter password: 

use test
db.createUser(
  {
    user: "msy",
    pwd: "123456",
    roles: [ { role: "readWrite", db: "write" },
             { role: "read", db: "read" } ]
  }
)

7.创建测试数据

use write
db.write.insert({"name":"zhangya","age":27,"ad":"北京市朝阳区"})
db.write.insert({"name":"zhangya","age":27,"ad":"北京市朝阳区"})
db.write.insert({"name":"yazhang","age":28,"ad":"北京市朝阳区"})
db.write.insert({"name":"xiaozhang","age":28,"ad":"北京市朝阳区"})
db.write.insert({"name":"xiaozhang","age":28,"ad":"北京市朝阳区","sex":"boy"})

use read
db.read.insert({"name":"zhangya","age":27,"ad":"北京市朝阳区"})
db.read.insert({"name":"zhangya","age":27,"ad":"北京市朝阳区"})
db.read.insert({"name":"yazhang","age":28,"ad":"北京市朝阳区"})
db.read.insert({"name":"xiaozhang","age":28,"ad":"北京市朝阳区"})
db.read.insert({"name":"xiaozhang","age":28,"ad":"北京市朝阳区","sex":"boy"})

8.退出admin,使用msy用户登录

验证库: 建立用户时use到的库,在使用用户时,要加上验证库才能登陆。

对于管理员用户,必须在admin下创建.
1. 建用户时,use到的库,就是此用户的验证库
2. 登录时,必须明确指定验证库才能登录
3. 通常,管理员用的验证库是admin,普通用户的验证库一般是所管理的库设置为验证库
4. 如果直接登录到数据库,不进行use,默认的验证库是test,不是我们生产建议的.
5. 从3.6 版本开始,不添加bindIp参数,默认不让远程登录,只能本地管理员登录。
[root@db01 ~]# mongo 10.0.0.51:27017 -umsy -p --authenticationDatabase test
MongoDB shell version v4.0.14
Enter password: 
use write
db.write.find()
{ "_id" : ObjectId("5e01fd296264b1cd8af9ff29"), "name" : "zhangya", "age" : 27, "ad" : "北京市朝阳区" }
...
> db.write.insert({"name":"zhangya","age":27,"ad":"北京市朝阳区"})
WriteResult({ "nInserted" : 1 })
> db.write.find()
{ "_id" : ObjectId("5e01fd296264b1cd8af9ff29"), "name" : "zhangya", 
{ "_id" : ObjectId("5e01fdb513bedd7dce9e9fed"), "name" : "zhangya", "age" : 27, "ad" : "北京市朝阳区" }
...
        
    
    
> use read
switched to db read
> db.write.find()
> db.write.insert({"name":"zhangya","age":27,"ad":"北京市朝阳区"})
WriteCommandError

9.修改用户权限

[root@db01 ~]# mongo 10.0.0.51:27017 -uadmin -p --authenticationDatabase admin
MongoDB shell version v4.0.14
Enter password: 

use test
db.updateUser(
  'msy',
  { 
    pwd: "123456",
    roles: [ { role: "readWrite", db: "write" },
             { role: "readWrite", db: "read" } ,
			 { role: "readWrite", db: "test" }
			 ]
			 
  }
)

10.删除用户

查看用户:
use admin
db.system.users.find().pretty()


db.getUsers()
db.dropUser('msy')
db.getUsers()
[ ]

use admin
db.getUsers()
[
	{
		"_id" : "admin.admin",
		"userId" : UUID("55238e0a-dcbc-4b52-9980-3c0cfd710f11"),
		"user" : "admin",
		"db" : "admin",
		"roles" : [
			{
				"role" : "root",
				"db" : "admin"
			}
		],
		"mechanisms" : [
			"SCRAM-SHA-1",
			"SCRAM-SHA-256"
		]
	}
]

第七章 mongo副本集配置

副本集?~= 一主两从

mongo副本集优点:

1.互相感知

2.自动故障转移

3.大多数投票选举 【至少三台】

4.不需要干涉 都是自动的

1.创建节点目录和数据目录

[root@db03 ~]# systemctl stop mongod
[root@db03 ~]# mkdir -p /opt/mongo_2801{7,8,9}/{conf,log,pid}
[root@db03 ~]# mkdir -p /data/mongo_2801{7,8,9}

2.创建配置文件

[root@db03 ~]# cat >/opt/mongo_28017/conf/mongo_28017.conf <<EOF
systemLog:
  destination: file   
  logAppend: true  
  path: /opt/mongo_28017/log/mongodb.log

storage:
  journal:
    enabled: true
  dbPath: /data/mongo_28017
  directoryPerDB: true
  wiredTiger:
     engineConfig:
        cacheSizeGB: 0.5 
        directoryForIndexes: true
     collectionConfig:
        blockCompressor: zlib
     indexConfig:
        prefixCompression: true

processManagement:
  fork: true
  pidFilePath: /opt/mongo_28017/pid/mongod.pid

net:
  port: 28017
  bindIp: 127.0.0.1,10.0.0.53

replication:
   oplogSizeMB: 1024 
   replSetName: dba
EOF

3.复制配置文件到其他节点

[root@db03 ~]# cp /opt/mongo_28017/conf/mongo_28017.conf /opt/mongo_28018/conf/mongo_28018.conf
[root@db03 ~]# cp /opt/mongo_28017/conf/mongo_28017.conf /opt/mongo_28019/conf/mongo_28019.conf

4.替换端口号

[root@db03 ~]# sed -i 's#28017#28018#g' /opt/mongo_28018/conf/mongo_28018.conf  
[root@db03 ~]# sed -i 's#28017#28019#g' /opt/mongo_28019/conf/mongo_28019.conf

5.启动所有节点

[root@db03 ~]# mongod -f /opt/mongo_28017/conf/mongo_28017.conf
[root@db03 ~]# mongod -f /opt/mongo_28018/conf/mongo_28018.conf
[root@db03 ~]# mongod -f /opt/mongo_28019/conf/mongo_28019.conf

6.初始化集群

# 登录三台多实例mongo
[root@db03 ~]# mongo 10.0.0.53:28017
[root@db03 ~]# mongo 10.0.0.53:28018
[root@db03 ~]# mongo 10.0.0.53:28019

# 在其中一台上初始化就可以 【这个就默认为主】
config = {
			_id : "dba", 
			members : [
						{_id : 0, host : "10.0.0.53:28017"},
						{_id : 1, host : "10.0.0.53:28018"},
						{_id : 2, host : "10.0.0.53:28019"},
			]}
rs.initiate(config) 

7.主库插入数据

dba:PRIMARY> db.inventory.insertMany( [
    { "item": "journal", "qty": 25, "size": { "h": 14, "w": 21, "uom": "cm" }, "status": "A" },
    { "item": "notebook", "qty": 50, "size": { "h": 8.5, "w": 11, "uom": "in" }, "status": "A" },
    { "item": "paper", "qty": 100, "size": { "h": 8.5, "w": 11, "uom": "in" }, "status": "D" },
    { "item": "planner", "qty": 75, "size": { "h": 22.85, "w": 30, "uom": "cm" }, "status": "D" },
    { "item": "postcard", "qty": 45, "size": { "h": 10, "w": 15.25, "uom": "cm" }, "status": "A" }
]);

8.副本节点登录查看数据

dba:SECONDARY> rs.slaveOk()
dba:SECONDARY> use test
dba:SECONDARY> db.inventory.find()

9.设置副本可读

方法1:临时生效
rs.slaveOk()

方法2:写入启动文件
echo "rs.slaveOk()" > ~/.mongorc.js

第八章 副本集权重调整

1.模拟故障转移

[root@db03 ~]# mongod -f /opt/mongo_28017/conf/mongo_28017.conf --shutdown
[root@db03 ~]# mongod -f /opt/mongo_28017/conf/mongo_28017.conf

2.查看当前副本集配置

dba:PRIMARY> rs.conf()
"_id" : 0,
			"host" : "10.0.0.53:28017",
			"arbiterOnly" : false,
			"buildIndexes" : true,
			"hidden" : false,
			"priority" : 1,
			"tags" : {
				
			},
			"slaveDelay" : NumberLong(0),
			"votes" : 1
		},
		{
			"_id" : 1,
			"host" : "10.0.0.53:28018",
			"arbiterOnly" : false,
			"buildIndexes" : true,
			"hidden" : false,
			"priority" : 100,
			"tags" : {
				
			},
			"slaveDelay" : NumberLong(0),
			"votes" : 1
		},
		{
			"_id" : 2,
			"host" : "10.0.0.53:28019",
			"arbiterOnly" : false,
			"buildIndexes" : true,
			"hidden" : false,
			"priority" : 1,
			"tags" : {

3.设置权重 在主库执行主库看

dba:PRIMARY> config=rs.conf()
dba:PRIMARY> config.members[1].priority=100
dba:PRIMARY> rs.reconfig(config)

dba:PRIMARY> rs.conf()
"_id" : 0,
			"host" : "10.0.0.53:28017",
			"arbiterOnly" : false,
			"buildIndexes" : true,
			"hidden" : false,
			"priority" : 1,
			"tags" : {
				
			},
			"slaveDelay" : NumberLong(0),
			"votes" : 1
		},
		{
			"_id" : 1,
			"host" : "10.0.0.53:28018",
			"arbiterOnly" : false,
			"buildIndexes" : true,
			"hidden" : false,
			"priority" : 100,
			"tags" : {
				
			},
			"slaveDelay" : NumberLong(0),
			"votes" : 1
		},
		{
			"_id" : 2,
			"host" : "10.0.0.53:28019",
			"arbiterOnly" : false,
			"buildIndexes" : true,
			"hidden" : false,
			"priority" : 1,
			"tags" : {
				
			},
			"slaveDelay" : NumberLong(0),
			"votes" : 1
		}

3.主节点主动降级

dba:PRIMARY> rs.stepDown()

4.恢复成默认的权重

暗箱操作 提升主库 毁尸灭迹

dba:PRIMARY> config=rs.conf()
dba:PRIMARY> config.members[0].priority=1
dba:PRIMARY> rs.reconfig(config)

第九章 增加新节点和删除旧节点

1.创建新节点并启动

[root@db03 ~]# mkdir -p /opt/mongo_28010/{conf,log,pid}
[root@db03 ~]# mkdir -p /data/mongo_28010
[root@db03 ~]#  /opt/mongo_28017/conf/mongo_28017.conf /opt/mongo_28010/conf/mongo_28010.conf
[root@db03 ~]# sed -i 's#28017#28010#g' /opt/mongo_28010/conf/mongo_28010.conf
[root@db03 ~]# mongod -f /opt/mongo_28010/conf/mongo_28010.conf
[root@db03 ~]# mongo 10.0.0.53:28010

2.集群添加节点[添加从库一个道理]

[root@db03 ~]# mongo 10.0.0.53:28017
dba:PRIMARY> use admin
dba:PRIMARY> rs.add("10.0.0.53:28010")

3.新节点查看信息

[root@db03 ~]# mongo 10.0.0.53:28010

4.删除节点

dba:PRIMARY> rs.remove("db01:28010")
dba:PRIMARY> rs.remove("db01:28011")

第十章 仲裁节点

注意:四台机器还是只能坏一台 多加一台仲裁节点 可以坏两台

1.什么是仲裁节点?

前面说一个副本集最少需要三台服务器,最多只能坏一台服务器。再选新主的时候需要大多数选举投票,这个时候我们可以加一个仲裁节点,只用于投票,不提供服务,不抢主机位。完美解决了两台服务器做副本集或多台服务器做副本集。

2.创建新节点并启动

[root@db03 ~]# mkdir -p /opt/mongo_28011/{conf,log,pid}
[root@db03 ~]# mkdir -p /data/mongo_28011
[root@db03 ~]# cp /opt/mongo_28017/conf/mongo_28017.conf /opt/mongo_28011/conf/mongo_28011.conf
[root@db03 ~]# sed -i 's#28017#28011#g' /opt/mongo_28011/conf/mongo_28011.conf
[root@db03 ~]# mongod -f /opt/mongo_28011/conf/mongo_28011.conf
[root@db03 ~]# mongo 10.0.0.53:28011

3.将仲裁节点加入集群

dba:PRIMARY> rs.addArb("10.0.0.53:28011")

[root@db03 ~]# mongo 10.0.0.53:28011
dba:ARBITER> 
dba:ARBITER> 

第十一章 mongo备份与恢复

1.工具介绍

1.mongoexport/mongoimport
2.mongodump/mongorestore

2.应用场景

1.异构平台迁移 mysql <---> mongodb
2.同平台,跨大版本:mongodb 2 ----> mongodb 3
3.mongoexport/mongoimport:json csv 格式

3.备份操作

# 1.单表备份
[root@db01 ~]# mongoexport --port 27017 -d test -c inventory -o /data/inventory.json
[root@db01 ~]# cat /data/inventory.json 
{"_id":{"$oid":"5e01f35e926392b74472fa96"},"item":"notebook","qty":50.0,"size":{"h":8.5,"w":11.0,"uom":"in"},"status":"A"}
{"_id":{"$oid":"5e01f35e926392b74472fa98"},"item":"planner","qty":75.0,"size":{"h":22.85,"w":30.0,"uom":"cm"},"status":"D"}


# 2.单表备份至csv格式 【可以直接导出 用excel打开】
[root@db01 ~]# mongoexport --port 27017 -d test -c user_info --type=csv -f name,age,ad -o /data/user_info.csv
[root@db01 ~]# cat /data/user_info.csv 
name,age,ad
sata,19,
sata,19,北京
jiu,69,北京
zhangya,27,北京市朝阳区
zhangya,27,北京市朝阳区
yazhang,28,北京市朝阳区
xiaozhang,28,北京市朝阳区
xiaozhang,28,北京市朝阳区


# 3.删表恢复
> db.inventory.drop()
true
> db.user_info.drop()
true
> show tables
> 

mongoimport --port 27017 -d test -c inventory /data/inventory.json

> show tables
inventory
user_info


# 4.mysql数据迁移到mongo
[root@db01 ~]# mysql < world.sql 

mysql> select * from world.city into outfile '/tmp/city.csv' fields terminated by ',';
ERROR 1290 (HY000): The MySQL server is running with the --secure-file-priv option so it cannot execute this statement

[root@db01 ~]# vim /etc/my.cnf
secure-file-priv=/tmp
[root@db01 ~]# systemctl restart mysqld

mysql> select * from world.city into outfile '/tmp/city.csv' fields terminated by ',';
Query OK, 4079 rows affected (0.04 sec)

[root@db01 ~]# vim /tmp/city.csv 
编辑csv文件,添加列名
ID,Name,CountryCode,District,Population

[root@db01 ~]# mongoimport --port 27017 -d world -c city --type=csv --headerline --file  /tmp/city.csv
[root@db01 ~]# mongoexport --port 27017 -d world -c city -o /tmp/city.json

> show databases
admin   0.000GB
config  0.000GB
local   0.000GB
read    0.000GB
test    0.000GB
world   0.000GB
write   0.000GB
> use world
switched to db world
> show tables
city


# 5.全备 导出与恢复
[root@db01 ~]# mongodump  --port 27017 -o /data/backup
[root@db01 ~]# mongorestore --port 27017 -d world  /data/backup/world/ --drop
[root@db01 ~]# mongorestore --port 27017 /data/backup/ --drop

第十二章 模拟误删除

1.oplog介绍

1.oplog是什么?
oplog即操作记录,是副本集成员特有的集合,默认为固定大小。
他是副本集之间同步数据的关键设计。
应用端对数据的增加,删除,修改操作都会被记录在这个集合中。

2.oplog的运作

在配置副本集时,若未指定Oplog大小,则Oplog默认为数据文件所在硬盘容量的5%,但默认大小不会超过50G
若自定义大小则不受限制,只需要在配置文件里使用oplogSizeMB参数即可
注意:此参数仅在集群未初始化前配置有效,一旦Oplog创建完集合,则再修改参数也无效
所以需要提前规划好数据写入的并发程度,如果设置的过小,可能导致还未同步到副本节点,oplog就已经满了

3.oplog的内容

oplog的内容会被记录在数据节点的local数据库中一个叫做oplog.rs的mongodb原生集合中。

2.操作命令

[注意在local里]
use local
db.oplog.rs.findOne()

内容解释:
ts: 操作时间
 h: 全局唯一标示
 v: oplog版本
op: 操作类型 
 i: 插入
 u: 更新
 d: 删除
 c: 执行指令
ns: 操作对象(集合)
 o: 操作的内容

3.oplog的初始化

如果是新增副本集,或者同步延迟太久,同步源的oplog领先太多,则会进行初始化
在初始化时,节点会从另一个副本成员进行完整的数据复制,包含整个数据文件及oplog的复制

4.oplog的同步

节点在同步时,会对比自身与其他节点的状态,从而选择数据比自己更完整的节点作为数据源进行同步。

5.查看oplog信息

rs.printReplicationInfo()

6.模拟误删除步骤

# 1.准备测试数据
use backup 
db.backup.insertMany( [
    { "id": 1},
    { "id": 2},
	{ "id": 3},
]);


# 2.全备环境
[root@db01 ~]# rm -rf /data/backup/*
[root@db01 ~]# mongodump --port 27018 --oplog -o /data/backup


# 3.增加新数据
[root@db01 ~]# mongo 
use backup 
db.backup.insertMany( [
    { "id": 4},
    { "id": 5},
	{ "id": 6},
]);


# 4.模拟删除集合
use backup 
db.backup.drop()


# 5.备份oplog [注意我这次全备的是local下的oplog]
[root@db01 ~]# mongodump --port 27018 -d local -c oplog.rs  -o /data/backup


# 6.查找误操作时间点
use local 
db.oplog.rs.find({ns:"backup.$cmd"}).pretty();


# 7.找到时间点信息
"ts" : Timestamp(1575023546, 1),


# 8.恢复数据
cd /data/backup/local/
cp oplog.rs.bson ../oplog.bson
rm -rf /data/backup/local/
mongorestore --port 27010 --oplogReplay --oplogLimit "1575023546:1"  --drop  /data/backup/
posted @ 2019-12-25 21:02  干瘪的柠檬  阅读(524)  评论(0)    收藏  举报