MongoDB管理学习笔记

MongoDB管理

一、 MongoDB安装

2.6开始主从复制已经淘汰,只是向后兼容以前的功能。
分类:单机部署、主从部署、副本集部署、分片部署四种架构
行叫文档,放到表里
表叫做集合,放到库里
库还是叫做库
是非关系型数据库(文档数据库)
官方下载站
http://www.mongodb.org/downloads
注册账号下载

环境: redhat 6.4 node3 192.168.0.5
安装
yum安装
If you are running a 64-bit system, use the following configuration:
[mongodb]
name=MongoDB Repository
baseurl=http://downloads-distro.mongodb.org/repo/redhat/os/x86_64/
gpgcheck=0
enabled=1
If you are running a 32-bit system, which is not recommended for production deployments, use the following configuration:
[mongodb]
name=MongoDB Repository
baseurl=http://downloads-distro.mongodb.org/repo/redhat/os/i686/
gpgcheck=0
enabled=1

yum install -y mongodb-org
rpm包安装
[root@node3 mongoDB]# ls
mongodb-org-2.6.4-1.x86_64.rpm mongodb-org-shell-2.6.4-1.x86_64.rpm
mongodb-org-mongos-2.6.4-1.x86_64.rpm mongodb-org-tools-2.6.4-1.x86_64.rpm
mongodb-org-server-2.6.4-1.x86_64.rpm
[root@node3 mongoDB]# rpm -ivh *
Preparing… ########################################### [100%]
1:mongodb-org-tools ########################################### [ 20%]
2:mongodb-org-shell ########################################### [ 40%]
3:mongodb-org-server ########################################### [ 60%]
4:mongodb-org-mongos ########################################### [ 80%]
5:mongodb-org ########################################### [100%]
配置文件
[root@node3 installation]# rpm -ql mongodb-org-server #提供数据库功能
/etc/mongod.conf #配置文件
/etc/rc.d/init.d/mongod #服务脚本
/etc/sysconfig/mongod
/usr/bin/mongod #服务启动命令
/usr/share/man/man1/mongod.1
/var/lib/mongo #数据库的路径
/var/log/mongodb
/var/log/mongodb/mongod.log #日志文件
/var/run/mongodb #运行的进程

[root@node3 installation]# rpm -ql mongodb-org-shell #客户端,连接mongoDB用
/usr/bin/mongo /usr/share/man/man1/mongo.1

[root@node3 installation]# rpm -ql mongodb-org-tools
#日志监控、关联、逻辑导入导出、性能状态、还原恢复等
/usr/bin/bsondump
/usr/bin/mongodump
/usr/bin/mongoexport
/usr/bin/mongofiles
/usr/bin/mongoimport
/usr/bin/mongooplog
/usr/bin/mongoperf
/usr/bin/mongorestore
/usr/bin/mongostat
/usr/bin/mongotop
/usr/share/man/man1/bsondump.1
/usr/share/man/man1/mongodump.1
/usr/share/man/man1/mongoexport.1
/usr/share/man/man1/mongofiles.1
/usr/share/man/man1/mongoimport.1
/usr/share/man/man1/mongooplog.1
/usr/share/man/man1/mongoperf.1
/usr/share/man/man1/mongorestore.1
/usr/share/man/man1/mongostat.1
/usr/share/man/man1/mongotop.1

[root@node3 installation]# rpm -ql mongodb-org-mongos
#做分片和路由时使用,是消息路由
/usr/bin/mongos
/usr/share/man/man1/mongos.1

[root@node3 installation]# rpm -ql mongodb-org
#没有任何包,只是基础包,装上面的依赖包
(contains no files)

vi /etc/mongod.conf
logpath=/var/log/mongodb/mongod.log #系统日志
logappend=true #进行日志追加
fork=true #放在后台运行
dbpath=/var/lib/mongo #数据文件存放位置
#port=27017 #进程号
bind_ip=127.0.0.1 #绑定IP,指定那个IP上运行
#nojournal=true #表示是否使用日志记录
#cpu=true #是否使用CPU管理策略
#noauth=true #这两个是安全策略设置,默认不使用密码登陆
#auth=true
#verbose=true #这两个调试时使用
#objcheck=true
#quota=true #是否对数据库限额,根据实际情况设置
#diaglog=0 #记录文档的信息,类似于oracle的redo和mysql的logfile功能,默认关闭
#httpinterface=true #是否打开通过web访问端口,默认28017

启动
1.[root@node3 mongoDB]# service mongod status
mongod is stopped
[root@node3 mongoDB]# service mongod start
Starting mongod: [ OK ]
[root@node3 mongoDB]# ps -ef|grep mongod
mongod 3993 1 0 22:59 ? 00:00:05 /usr/bin/mongod -f /etc/mongod.conf

2.也可以附带调用一个http的界面,可以通过web访问的启动
[root@node3 mongoDB]# service mongod stop
[root@node3 installation]# mongod -f /etc/mongod.conf --httpinterface
about to fork child process, waiting until server is ready for connections.
forked process: 4520
child process started successfully, parent exiting

3.#mongod --syslog #将日志放到系统日志里
4.#mongod --logpath /var/log/mongodb/mongod.log --logappend #指定日志存放目录并将后续日志进行追加
登陆
[root@node3 mongoDB]# mongo
MongoDB shell version: 2.6.4
connecting to: test

关库
1.service mongod stop
2.可以切换到admin进行关库

use admin 或 [root@node3 ~]# mongo admin
db.help #查看带db命令的帮助
db.stats() #查看库的状态
db.shutdownServer() #关库
db.stats()
show collections #显示当前数据库下已有collection
show profile #显示花费了1ms以上的前5个操作

db.currentOp() #查看活动进程,便于了解系统正在做什么,以便做下一步判断
字段说明:Opid:操作进程号,Op:操作类型(查询,更新等),Ns:命名空间,指操作的是哪个对象,Query:如果操作类型是查询的话,这里将显示具体的查询那内容,lockType:锁的类型,指明是读锁还是写锁
db.killOp(1234/opid/) #杀进程

主从操作日志oplog
MongoDB的replica Set架构师通过一个日志来存储写操作的,这个日志就叫做“oplog”。oplog.rs是一个固定长度的capped collection,它存在于“local”数据库中,用于记录replica sets操作日志。在默认情况下,对于64位的MongDB,oplog是比较大的,可以达到5%的磁盘空间。oplog的大小是可以通过mongod的参数”—oplogSize来改变oplog的日志大小。

use local
show collections
db.oplog.rs.find()
字段说明:
ts:某个操作的时间戳
op:操作类型,如下:
i;insert d:delete u:update
ns:命令空间,也就是操作的collection name
o: document的内容
主从配置信息
use local
show collections
db.system.replset.find()
rs.conf()
让从库可以读,分担主库的压力
set1:SECONDARY> use test
switched to db test
set1:SECONDARY> show collections
2019-01-27T22:23:18.108-0800 error: { “$err” : “not master and slaveOk=false”, “code” : 13435 } at src/mongo/shell/query.js:131
set1:SECONDARY> db.getMongo().setSlaveOk()
set1:SECONDARY> show collections
com
system.indexes
t5

CRUD(create、insert、update、delete)
建立: db<库>.insert(文档)
读: db<库>.find() #默认所有,可以查找指定的结果eg:> db.t.t.find({“NAME” : “WORK”})
db<库>.findOne() #只找第一条
更新: db<库>.update()
删除: db<库>.remove()
查询
WriteResult({ “nMatched” : 1, “nUpserted” : 0, “nModified” : 0 })

show dbs
admin (empty)
local 0.078GB
show databases;
admin (empty)
local 0.078GB
use admin;
switched to db admin
local
use local;
switched to db local
db #当前是哪个库
local
show tables; 或> show collections; #集合
startup_log
system.indexes
db.startup_log.find() #查询startup_log集合中有哪些行
插入(创建)数据
db.users.insert({name:“sue”,age:26,status:“A”})
WriteResult({ “nInserted” : 1 })
db.inventory.insert({_id:10,type:“misc”,item:“card”,qty:15})
WriteResult({ “nInserted” : 1 })
更改数据
update更改数据
db.users.update({age:{KaTeX parse error: Expected 'EOF', got '}' at position 6: gt:18}̲},{set:{status:“A”}},{multi:true});
WriteResult({ “nMatched” : 1, “nUpserted” : 0, “nModified” : 0 })
db.inventory.update({type:“book”,item:“journal”},{$set:{qty:10}},{upsert:true})

update默认只对一行更新,若要对多行进行更新要使用multi选项,若没有指定类似set的参数,就会把所有影响的文档替换,当更新时,文档的大小超过了原先分配的大小,那么会重新分配空间,然后把文档放入,这样会导致文档内的字段重排。
使用update插入文档的时候要指明upsert:true,表示如果有数据则修改,没数据则插入
插入的文档如果没有指定_id_mongodb会自动分配一个_id。
save更改数据

db.inventory.save({type:“book”,item:“notebook”,qty:40});
WriteResult({ “nInserted” : 1 })
删除数据
db.users.remove({status:“D”})
WriteResult({ “nRemoved” : 0 })
删除数据库
use dept
db
set1:PRIMARY> db.dropDatabase()
{ “dropped” : “dept”, “ok” : 1 }

二、mongodb基础

文档与集合数据库的概念
文档是数据的基本单元,类似关系数据库的行,但比行复杂。
集合相当于没有模式的表。
一个实例可容纳多个独立的库,每个库都有自己的集合和权限
每个文档都有一个特殊的键“_id”在集合中唯一
文档:
文档是核心概念,多个键及其关联的值有序放在一起就是文档。
文档的键/值对是有序的,值可以是任和数据类型,但不能含有\0(空字符),.和KaTeX parse error: Undefined control sequence: \0 at position 181: …度。 集合不能空字符、不能含有\̲0̲,不能system开头,不能还…
集合可以使用连接集合 比如blog.auth 使用“.”分隔的也叫子集合。
数据库:
文档组成集合,集合组成库。一个实例可以多个库。
库各自独立的,每个库有自己独立的权限控制,就是磁盘上的文件也不同。
库不能含有空字符,“,$/\ \0
通常小写,最多64字节
不能使用保留的库名admin local config
可以切不存在的库
可以插入不存在的库的数据(instert),show dbs就会发现创建了
admin:root库,一个用户添加到这个库,继承所有库的权限。用于授权、管理库
local:不能被复制,存储本地单实例的任意集合
config:用于分片设置,保留分片信息

CRUD综合应用实例
1.oracle生成能在mongodb插入的数据格式:
SQL> conn scott/tiger
SQL> select ‘db.dept.insert({deptno:’||deptno||’,dname:"’||dname||’",loc:"’||loc||’"});’ from dept;

‘DB.DEPT.INSERT({DEPTNO:’||DEPTNO||’,DNAME:"’||DNAME||’",LOC:"’||LOC||’"});’

db.dept.insert({deptno:10,dname:“ACCOUNTING”,loc:“NEW YORK”});
db.dept.insert({deptno:20,dname:“RESEARCH”,loc:“DALLAS”});
db.dept.insert({deptno:30,dname:“SALES”,loc:“CHICAGO”});
db.dept.insert({deptno:40,dname:“OPERATIONS”,loc:“BOSTON”});

2.插入到mongodb上
[root@node3 ~]# mongo
MongoDB shell version: 2.6.4
connecting to: test

db.dept.find();
{ “_id” : ObjectId(“5c45592922372b4cd315c85f”), “deptno” : 10, “dname” : “ACCOUNTING”, “loc” : “NEW YORK” }
{ “_id” : ObjectId(“5c45592a22372b4cd315c860”), “deptno” : 20, “dname” : “RESEARCH”, “loc” : “DALLAS” }
{ “_id” : ObjectId(“5c45592a22372b4cd315c861”), “deptno” : 30, “dname” : “SALES”, “loc” : “CHICAGO” }
{ “_id” : ObjectId(“5c45592b22372b4cd315c862”), “deptno” : 40, “dname” : “OPERATIONS”, “loc” : “BOSTON” }

db.dept.update({deptno:40},{KaTeX parse error: Expected 'EOF', got '}' at position 20: …{loc:"Beijing"}}̲) #set 修改为北京 {deptno:40}相当于mysql中的where
WriteResult({ “nMatched” : 1, “nUpserted” : 0, “nModified” : 1 })
db.dept.find()
{ “_id” : ObjectId(“5c45592922372b4cd315c85f”), “deptno” : 10, “dname” : “ACCOUNTING”, “loc” : “NEW YORK” }
{ “_id” : ObjectId(“5c45592a22372b4cd315c860”), “deptno” : 20, “dname” : “RESEARCH”, “loc” : “DALLAS” }
{ “_id” : ObjectId(“5c45592a22372b4cd315c861”), “deptno” : 30, “dname” : “SALES”, “loc” : “CHICAGO” }
{ “_id” : ObjectId(“5c45592b22372b4cd315c862”), “deptno” : 40, “dname” : “OPERATIONS”, “loc” : “Beijing” }

db.dept.update({deptno:40},{KaTeX parse error: Expected 'EOF', got '}' at position 15: inc:{deptno:2}}̲); #inc 加2
WriteResult({ “nMatched” : 1, “nUpserted” : 0, “nModified” : 1 })
db.dept.find()
{ “_id” : ObjectId(“5c45592922372b4cd315c85f”), “deptno” : 10, “dname” : “ACCOUNTING”, “loc” : “NEW YORK” }
{ “_id” : ObjectId(“5c45592a22372b4cd315c860”), “deptno” : 20, “dname” : “RESEARCH”, “loc” : “DALLAS” }
{ “_id” : ObjectId(“5c45592a22372b4cd315c861”), “deptno” : 30, “dname” : “SALES”, “loc” : “CHICAGO” }
{ “_id” : ObjectId(“5c45592b22372b4cd315c862”), “deptno” : 42, “dname” : “OPERATIONS”, “loc” : “Beijing” }

db.dept.update({deptno:42},{KaTeX parse error: Expected 'EOF', got '}' at position 16: inc:{deptno:-2}}̲); #inc 减2
WriteResult({ “nMatched” : 1, “nUpserted” : 0, “nModified” : 1 })
db.dept.find()
{ “_id” : ObjectId(“5c45592922372b4cd315c85f”), “deptno” : 10, “dname” : “ACCOUNTING”, “loc” : “NEW YORK” }
{ “_id” : ObjectId(“5c45592a22372b4cd315c860”), “deptno” : 20, “dname” : “RESEARCH”, “loc” : “DALLAS” }
{ “_id” : ObjectId(“5c45592a22372b4cd315c861”), “deptno” : 30, “dname” : “SALES”, “loc” : “CHICAGO” }
{ “_id” : ObjectId(“5c45592b22372b4cd315c862”), “deptno” : 40, “dname” : “OPERATIONS”, “loc” : “Beijing” }

db.dept.update({deptno:50},{$set:{tel:"(010-66667777)"}},true);
WriteResult({
“nMatched” : 0,
“nUpserted” : 1,
“nModified” : 0,
“_id” : ObjectId(“5c458c44d274ac06c35b519d”)})
db.dept.find()
{ “_id” : ObjectId(“5c45592922372b4cd315c85f”), “deptno” : 10, “dname” : “ACCOUNTING”, “loc” : “NEW YORK” }
{ “_id” : ObjectId(“5c45592a22372b4cd315c860”), “deptno” : 20, “dname” : “RESEARCH”, “loc” : “DALLAS” }
{ “_id” : ObjectId(“5c45592a22372b4cd315c861”), “deptno” : 30, “dname” : “SALES”, “loc” : “CHICAGO” }
{ “_id” : ObjectId(“5c45592b22372b4cd315c862”), “deptno” : 40, “dname” : “OPERATIONS”, “loc” : “Beijing” }
{ “_id” : ObjectId(“5c458db7d274ac06c35b519e”), “deptno” : 50, “tel” : “(010-66667777)” }

db.dept.insert({deptno:50,tel:"(010-66667777)"});
WriteResult({ “nInserted” : 1 })
db.dept.find() #两条重复行
{ “_id” : ObjectId(“5c45592922372b4cd315c85f”), “deptno” : 10, “dname” : “ACCOUNTING”, “loc” : “NEW YORK” }
{ “_id” : ObjectId(“5c45592a22372b4cd315c860”), “deptno” : 20, “dname” : “RESEARCH”, “loc” : “DALLAS” }
{ “_id” : ObjectId(“5c45592a22372b4cd315c861”), “deptno” : 30, “dname” : “SALES”, “loc” : “CHICAGO” }
{ “_id” : ObjectId(“5c45592b22372b4cd315c862”), “deptno” : 40, “dname” : “OPERATIONS”, “loc” : “Beijing” }
{ “_id” : ObjectId(“5c458db7d274ac06c35b519e”), “deptno” : 50, “tel” : “(010-66667777)” }
{ “_id” : ObjectId(“5c4592e222372b4cd315c870”), “deptno” : 50, “tel” : “(010-66667777)” }
db.dept.update({deptno:50},{$set:{tel:"(010-66668888)"}});
WriteResult({ “nMatched” : 1, “nUpserted” : 0, “nModified” : 1 })
db.dept.find() #更改了第一个重复的文档
{ “_id” : ObjectId(“5c45592922372b4cd315c85f”), “deptno” : 10, “dname” : “ACCOUNTING”, “loc” : “NEW YORK” }
{ “_id” : ObjectId(“5c45592a22372b4cd315c860”), “deptno” : 20, “dname” : “RESEARCH”, “loc” : “DALLAS” }
{ “_id” : ObjectId(“5c45592a22372b4cd315c861”), “deptno” : 30, “dname” : “SALES”, “loc” : “CHICAGO” }
{ “_id” : ObjectId(“5c45592b22372b4cd315c862”), “deptno” : 40, “dname” : “OPERATIONS”, “loc” : “Beijing” }
{ “_id” : ObjectId(“5c458db7d274ac06c35b519e”), “deptno” : 50, “tel” : “(010-66668888)” }
{ “_id” : ObjectId(“5c4592e222372b4cd315c870”), “deptno” : 50, “tel” : “(010-66667777)” }

db.dept.update({deptno:50},{$set:{tel:"(010-66668888)"}},false,true); #所有都改
WriteResult({ “nMatched” : 2, “nUpserted” : 0, “nModified” : 1 })
db.dept.find() #都改了,
{ “_id” : ObjectId(“5c45592922372b4cd315c85f”), “deptno” : 10, “dname” : “ACCOUNTING”, “loc” : “NEW YORK” }
{ “_id” : ObjectId(“5c45592a22372b4cd315c860”), “deptno” : 20, “dname” : “RESEARCH”, “loc” : “DALLAS” }
{ “_id” : ObjectId(“5c45592a22372b4cd315c861”), “deptno” : 30, “dname” : “SALES”, “loc” : “CHICAGO” }
{ “_id” : ObjectId(“5c45592b22372b4cd315c862”), “deptno” : 40, “dname” : “OPERATIONS”, “loc” : “Beijing” }
{ “_id” : ObjectId(“5c458db7d274ac06c35b519e”), “deptno” : 50, “tel” : “(010-66668888)” }
{ “_id” : ObjectId(“5c4592e222372b4cd315c870”), “deptno” : 50, “tel” : “(010-66668888)” }

db.dept.update({deptno:50},{KaTeX parse error: Expected 'EOF', got '}' at position 28: …(010-6668888)"}}̲); #unset删除一个列
WriteResult({ “nMatched” : 1, “nUpserted” : 0, “nModified” : 1 })
db.dept.find()
{ “_id” : ObjectId(“5c45592922372b4cd315c85f”), “deptno” : 10, “dname” : “ACCOUNTING”, “loc” : “NEW YORK” }
{ “_id” : ObjectId(“5c45592a22372b4cd315c860”), “deptno” : 20, “dname” : “RESEARCH”, “loc” : “DALLAS” }
{ “_id” : ObjectId(“5c45592a22372b4cd315c861”), “deptno” : 30, “dname” : “SALES”, “loc” : “CHICAGO” }
{ “_id” : ObjectId(“5c45592b22372b4cd315c862”), “deptno” : 40, “dname” : “OPERATIONS”, “loc” : “Beijing” }
{ “_id” : ObjectId(“5c458db7d274ac06c35b519e”), “deptno” : 50 }
{ “_id” : ObjectId(“5c4592e222372b4cd315c870”), “deptno” : 50, “tel” : “(010-66668888)” }

db.dept.update({deptno:50},{$unset:{tel:"(010-6668888)"}},false,true); #删除多行指定的列
WriteResult({ “nMatched” : 2, “nUpserted” : 0, “nModified” : 1 })
db.dept.find()
{ “_id” : ObjectId(“5c45592922372b4cd315c85f”), “deptno” : 10, “dname” : “ACCOUNTING”, “loc” : “NEW YORK” }
{ “_id” : ObjectId(“5c45592a22372b4cd315c860”), “deptno” : 20, “dname” : “RESEARCH”, “loc” : “DALLAS” }
{ “_id” : ObjectId(“5c45592a22372b4cd315c861”), “deptno” : 30, “dname” : “SALES”, “loc” : “CHICAGO” }
{ “_id” : ObjectId(“5c45592b22372b4cd315c862”), “deptno” : 40, “dname” : “OPERATIONS”, “loc” : “Beijing” }
{ “_id” : ObjectId(“5c458db7d274ac06c35b519e”), “deptno” : 50 }
{ “_id” : ObjectId(“5c4592e222372b4cd315c870”), “deptno” : 50 }

db.dept.remove({deptno:50}); #删除所有符合条件的行(文档)
WriteResult({ “nRemoved” : 2 })
db.dept.find()
{ “_id” : ObjectId(“5c45592922372b4cd315c85f”), “deptno” : 10, “dname” : “ACCOUNTING”, “loc” : “NEW YORK” }
{ “_id” : ObjectId(“5c45592a22372b4cd315c860”), “deptno” : 20, “dname” : “RESEARCH”, “loc” : “DALLAS” }
{ “_id” : ObjectId(“5c45592a22372b4cd315c861”), “deptno” : 30, “dname” : “SALES”, “loc” : “CHICAGO” }
{ “_id” : ObjectId(“5c45592b22372b4cd315c862”), “deptno” : 40, “dname” : “OPERATIONS”, “loc” : “Beijing” }

db.dept.remove({deptno:{$gt::50}}); #删除大于50的行
WriteResult({ “nRemoved” : 0 })

db.dept.drop() #删除表/删除所有行
True

show dbs
admin (empty)
local 0.078GB
test 0.078GB
use test;
switched to db test
db #当前库
Test
show collections
dept
inventory
system.indexes
test.emp
Users
db.salgrade.find()
{ “_id” : ObjectId(“5c459e77537641d64fe4e723”), “grade” : 1, “losal” : 700, “hisal” : 1200 }
{ “_id” : ObjectId(“5c459e77537641d64fe4e724”), “grade” : 2, “losal” : 1201, “hisal” : 1400 }
{ “_id” : ObjectId(“5c459e77537641d64fe4e725”), “grade” : 3, “losal” : 1401, “hisal” : 2000 }
{ “_id” : ObjectId(“5c459e77537641d64fe4e726”), “grade” : 4, “losal” : 2001, “hisal” : 3000 }
{ “_id” : ObjectId(“5c459e77537641d64fe4e727”), “grade” : 5, “losal” : 3001, “hisal” : 9999 }
db.salgrade.find({},{grade:1}); #只找指定一个列
{ “_id” : ObjectId(“5c459e77537641d64fe4e723”), “grade” : 1 }
{ “_id” : ObjectId(“5c459e77537641d64fe4e724”), “grade” : 2 }
{ “_id” : ObjectId(“5c459e77537641d64fe4e725”), “grade” : 3 }
{ “_id” : ObjectId(“5c459e77537641d64fe4e726”), “grade” : 4 }
{ “_id” : ObjectId(“5c459e77537641d64fe4e727”), “grade” : 5 }

db.salgrade.find({},{_id:0,grade:1}); #去掉_id列的显示
{ “grade” : 1 }
{ “grade” : 2 }
{ “grade” : 3 }
{ “grade” : 4 }
{ “grade” : 5 }

db.salgrade.find({},{_id:0,grade:1,losal:1}); #多列查询
{ “grade” : 1, “losal” : 700 }
{ “grade” : 2, “losal” : 1201 }
{ “grade” : 3, “losal” : 1401 }
{ “grade” : 4, “losal” : 2001 }
{ “grade” : 5, “losal” : 3001 }

db.salgrade.find({},{grade:0}); #除了grade列不要,其它列都要
{ “_id” : ObjectId(“5c459e77537641d64fe4e723”), “losal” : 700, “hisal” : 1200 }
{ “_id” : ObjectId(“5c459e77537641d64fe4e724”), “losal” : 1201, “hisal” : 1400 }
{ “_id” : ObjectId(“5c459e77537641d64fe4e725”), “losal” : 1401, “hisal” : 2000 }
{ “_id” : ObjectId(“5c459e77537641d64fe4e726”), “losal” : 2001, “hisal” : 3000 }
{ “_id” : ObjectId(“5c459e77537641d64fe4e727”), “losal” : 3001, “hisal” : 9999 }

db.salgrade.find({},{_id:0,grade:0});
{ “losal” : 700, “hisal” : 1200 }
{ “losal” : 1201, “hisal” : 1400 }
{ “losal” : 1401, “hisal” : 2000 }
{ “losal” : 2001, “hisal” : 3000 }
{ “losal” : 3001, “hisal” : 9999 }

db.emp.find({},{_id:0,deptno:1})
{ “deptno” : 20 }
{ “deptno” : 30 }
{ “deptno” : 30 }
………….
db.emp.distinct(‘deptno’); #去重(去除重复的行)
[ 20, 30, 10 ]

db.emp.findOne({},{_id:0,ename:1}) #findOne只找第一行(可以指定列)
{ “ename” : “SMITH” }

db.emp.find().limit(2) #.limit 查找前2条
{ “_id” : ObjectId(“5c45a32b537641d64fe4e728”), “empno” : 7369, “ename” : “SMITH”, “deptno” : 20, “job” : “CLERK” }
{ “_id” : ObjectId(“5c45a32b537641d64fe4e729”), “empno” : 7499, “ename” : “ALLEN”, “deptno” : 30, “job” : “SALESMAN” }

db.emp.find().limit(2),skip(1) #跳过第一行,查找前两行
2019-01-21T02:55:44.121-0800 ReferenceError: skip is not defined
db.emp.find().limit(2).skip(1)
{ “_id” : ObjectId(“5c45a32b537641d64fe4e729”), “empno” : 7499, “ename” : “ALLEN”, “deptno” : 30, “job” : “SALESMAN” }
{ “_id” : ObjectId(“5c45a32b537641d64fe4e72a”), “empno” : 7521, “ename” : “WARD”, “deptno” : 30, “job” : “SALESMAN” }

db.emp.find().skip(10) #跳过前10行,从第11行开始
{ “_id” : ObjectId(“5c45a32d537641d64fe4e732”), “empno” : 7876, “ename” : “ADAMS”, “deptno” : 20, “job” : “CLERK” }
{ “_id” : ObjectId(“5c45a334537641d64fe4e733”), “empno” : 7900, “ename” : “JAMES”, “deptno” : 30, “job” : “CLERK” }
{ “_id” : ObjectId(“5c45a334537641d64fe4e734”), “empno” : 7902, “ename” : “FORD”, “deptno” : 20, “job” : “ANALYST” }
{ “_id” : ObjectId(“5c45a334537641d64fe4e735”), “empno” : 7934, “ename” : “MILLER”, “deptno” : 10, “job” : “CLERK” }

db.emp.find().skip(10).limit(3) #相当于between…and的用法
{ “_id” : ObjectId(“5c45a32d537641d64fe4e732”), “empno” : 7876, “ename” : “ADAMS”, “deptno” : 20, “job” : “CLERK” }
{ “_id” : ObjectId(“5c45a334537641d64fe4e733”), “empno” : 7900, “ename” : “JAMES”, “deptno” : 30, “job” : “CLERK” }
{ “_id” : ObjectId(“5c45a334537641d64fe4e734”), “empno” : 7902, “ename” : “FORD”, “deptno” : 20, “job” : “ANALYST” }

db.emp.find({deptno:10}) #查找部门编号10的行,相当于where
{ “_id” : ObjectId(“5c45a32b537641d64fe4e72e”), “empno” : 7782, “ename” : “CLARK”, “deptno” : 10, “job” : “MANAGER” }
{ “_id” : ObjectId(“5c45a32b537641d64fe4e730”), “empno” : 7839, “ename” : “KING”, “deptno” : 10, “job” : “PRESIDENT” }
{ “_id” : ObjectId(“5c45a334537641d64fe4e735”), “empno” : 7934, “ename” : “MILLER”, “deptno” : 10, “job” : “CLERK” }

db.emp.find({deptno:{KaTeX parse error: Expected 'EOF', got '}' at position 6: lt:20}̲}) #lt是查找小于20行, g t 是 大 于 . gt是大于. gt.gte大于等于, l t e 小 于 等 于 , lte小于等于, ltene不等于
{ “_id” : ObjectId(“5c45a32b537641d64fe4e72e”), “empno” : 7782, “ename” : “CLARK”, “deptno” : 10, “job” : “MANAGER” }
{ “_id” : ObjectId(“5c45a32b537641d64fe4e730”), “empno” : 7839, “ename” : “KING”, “deptno” : 10, “job” : “PRESIDENT” }
{ “_id” : ObjectId(“5c45a334537641d64fe4e735”), “empno” : 7934, “ename” : “MILLER”, “deptno” : 10, “job” : “CLERK” }

db.emp.find({deptno:{$in:[20,30,40]}},{deptno:1})
#指定那些值,查询指定的列(相当于select deptno from emp where deptno in(20,30,40))
KaTeX parse error: Expected '}', got 'EOF' at end of input: ….find({deptno:{nin:[20,30,40]}},{deptno:1})
{ “_id” : ObjectId(“5c45a32b537641d64fe4e72e”), “deptno” : 10 }
{ “_id” : ObjectId(“5c45a32b537641d64fe4e730”), “deptno” : 10 }
{ “_id” : ObjectId(“5c45a334537641d64fe4e735”), “deptno” : 10 }

db.emp.find({deptno:{KaTeX parse error: Expected 'EOF', got '}' at position 7: gte:20}̲,deptno:{lte:30}},{deptno:1}) #相当于or
{ “_id” : ObjectId(“5c45a32b537641d64fe4e728”), “deptno” : 20 }
{ “_id” : ObjectId(“5c45a32b537641d64fe4e729”), “deptno” : 30 }
{ “_id” : ObjectId(“5c45a32b537641d64fe4e72a”), “deptno” : 30 }
……. …….
db.emp.find({deptno:{ g t e : 20 , gte:20, gte:20,lte:30}},{deptno:1}) #between…and…
{ “_id” : ObjectId(“5c45a32b537641d64fe4e728”), “deptno” : 20 }
{ “_id” : ObjectId(“5c45a32b537641d64fe4e729”), “deptno” : 30 }
{ “_id” : ObjectId(“5c45a32b537641d64fe4e72a”), “deptno” : 30 }
…… …….

db.emp.find().sort({empno:1}) #升序排列,-1为降序排列
{ “_id” : ObjectId(“5c45a32b537641d64fe4e728”), “empno” : 7369, “ename” : “SMITH”, “deptno” : 20, “job” : “CLERK” }
{ “_id” : ObjectId(“5c45a32b537641d64fe4e729”), “empno” : 7499, “ename” : “ALLEN”, “deptno” : 30, “job” : “SALESMAN” }
{ “_id” : ObjectId(“5c45a32b537641d64fe4e72a”), “empno” : 7521, “ename” : “WARD”, “deptno” : 30, “job” : “SALESMAN” }
…… …….
db.emp.find({},{empno:1,_id:0}).sort({empno:1})
{ “empno” : 7369 }
{ “empno” : 7499 }
{ “empno” : 7521 }
db.emp.find({},{empno:1,_id:0}).sort({empno:-1})
{ “empno” : 7934 }
{ “empno” : 7902 }
{ “empno” : 7900 }

db.emp.find({KaTeX parse error: Expected '}', got 'EOF' at end of input: or:[{empno:{lt:7600}},{empno:{$gt:7900}}]},{empno:1})
小于7600或大于7900的查询结果 =not…between_and
{ “_id” : ObjectId(“5c45a32b537641d64fe4e728”), “empno” : 7369 }
{ “_id” : ObjectId(“5c45a32b537641d64fe4e729”), “empno” : 7499 }
{ “_id” : ObjectId(“5c45a32b537641d64fe4e72a”), “empno” : 7521 }
{ “_id” : ObjectId(“5c45a32b537641d64fe4e72b”), “empno” : 7566 }
{ “_id” : ObjectId(“5c45a334537641d64fe4e734”), “empno” : 7902 }
{ “_id” : ObjectId(“5c45a334537641d64fe4e735”), “empno” : 7934 }

db.emp.find({empno:{$mod:[6,1]}}) #求除6余1的查询结果
{ “_id” : ObjectId(“5c45a32b537641d64fe4e728”), “empno” : 7369, “ename” : “SMITH”, “deptno” : 20, “job” : “CLERK” }

db.emp.find({empno:{KaTeX parse error: Expected '}', got 'EOF' at end of input: not:{lt:7920}}}) #$not取反
{ “_id” : ObjectId(“5c45a334537641d64fe4e735”), “empno” : 7934, “ename” : “MILLER”, “deptno” : 10, “job” : “CLERK” }
正则表达式
db.emp.find({ename:/^A/}) #查找指定列以A开头的行
{ “_id” : ObjectId(“5c45a32b537641d64fe4e729”), “empno” : 7499, “ename” : “ALLEN”, “deptno” : 30, “job” : “SALESMAN” }
{ “_id” : ObjectId(“5c45a32d537641d64fe4e732”), “empno” : 7876, “ename” : “ADAMS”, “deptno” : 20, “job” : “CLERK” }

db.emp.find({ename:/^a/i}) #加上i为大小写不区分
{ “_id” : ObjectId(“5c45a32b537641d64fe4e729”), “empno” : 7499, “ename” : “ALLEN”, “deptno” : 30, “job” : “SALESMAN” }
{ “_id” : ObjectId(“5c45a32d537641d64fe4e732”), “empno” : 7876, “ename” : “ADAMS”, “deptno” : 20, “job” : “CLERK” }

db.emp.find({ename:/GKaTeX parse error: Expected 'EOF', got '}' at position 3: /i}̲) #加为查找指定列G结尾的行
{ “_id” : ObjectId(“5c45a32b537641d64fe4e730”), “empno” : 7839, “ename” : “KING”, “deptno” : 10, “job” : “PRESIDENT” }

db.emp.find({ename:/T.$/i})
#指定列倒数第二个字符为T的行,有几个点就有代表几个字符
{ “_id” : ObjectId(“5c45a32b537641d64fe4e728”), “empno” : 7369, “ename” : “SMITH”, “deptno” : 20, “job” : “CLERK” }
{ “_id” : ObjectId(“5c45a32b537641d64fe4e72f”), “empno” : 7788, “ename” : “SCOTT”, “deptno” : 20, “job” : “ANALYST” }

db.emp.find({ename:/.+A/i}) #查找多个字符为A的行
{ “_id” : ObjectId(“5c45a32b537641d64fe4e72a”), “empno” : 7521, “ename” : “WARD”, “deptno” : 30, “job” : “SALESMAN” }
{ “_id” : ObjectId(“5c45a32b537641d64fe4e72c”), “empno” : 7654, “ename” : “MARTIN”, “deptno” : 30, “job” : “SALESMAN” }
…… ……

db.dept.find({dname:{$not:/^A./}}) #查询不匹配dname=A带头的记录
更多操作见《MongoDB_权威指南_中文版》

聚合操作
Count()

db.emp.count() #统计行数count(*)
14
db.emp.count({},{empno:1}) #统计count(empno)
14
sum
db.emp.aggregate({KaTeX parse error: Expected '}', got 'EOF' at end of input: …:" ",sumempno:{sum:"KaTeX parse error: Expected 'EOF', got '}' at position 7: empno"}̲}}) #aggregate聚…sum统计关键字可换成其它的函数表达式,$empno跟的是真实的列名 =sum(empno)
{ “_id” : " ", “sumempno” : 108172 }

group

db.emp.aggregate({KaTeX parse error: Expected '}', got 'EOF' at end of input: group:{_id:"empno",sumempno:{ s u m : " sum:" sum:"empno"}}}) #进行分组sum
{ “_id” : 7902, “sumempno” : 7902 }
{ “_id” : 7900, “sumempno” : 7900 }
{ “_id” : 7934, “sumempno” : 7934 }
{ “_id” : 7876, “sumempno” : 7876 }
{ “_id” : 7788, “sumempno” : 7788 }

db.emp.aggregate({KaTeX parse error: Expected '}', got 'EOF' at end of input: …:{_id:{deptno:"deptno"},sumdeptno:{ s u m : " sum:" sum:"deptno"}}})
#加列名进行分组
{ “_id” : { “deptno” : 10 }, “sumdeptno” : 30 }
{ “_id” : { “deptno” : 30 }, “sumdeptno” : 180 }
{ “_id” : { “deptno” : 20 }, “sumdeptno” : 100 }

db.emp.aggregate({KaTeX parse error: Expected '}', got 'EOF' at end of input: …:{_id:{deptno:"deptno",job:"KaTeX parse error: Expected 'EOF', got '}' at position 5: job"}̲,sumdeptno:{sum:“KaTeX parse error: Expected 'EOF', got '}' at position 8: deptno"}̲}}) #在部门的基础上在进行…group:{_id:{deptno:“ d e p t n o " , j o b : " deptno",job:" deptno",job:"job”},sumdeptno:{ s u m : " sum:" sum:"deptno”}}},{KaTeX parse error: Expected '}', got 'EOF' at end of input: …ch:{sumdeptno:{gt:40}}})
#match在分组的基础上再进行过滤 =having
{ “_id” : { “deptno” : 30, “job” : “SALESMAN” }, “sumdeptno” : 120 }

exists

db.dept.find({deptno:{KaTeX parse error: Expected 'EOF', got '}' at position 12: exists:true}̲}) #查询所有存在de…exists:false}}) #查询所有不存在deptno字段的记录

三、索引

查看索引

db.emp.getIndexes() #查看索引
[
{
“v” : 1,
“key” : {
“_id” : 1 #默认索引_id
},
“name” : “id”,
“ns” : “test.emp”
}
]
建立索引
db.emp.ensureIndex({empno:1}) #建立一个升序(1)索引,-1为降序
{
“createdCollectionAutomatically” : false,
“numIndexesBefore” : 1,
“numIndexesAfter” : 2,
“ok” : 1 #表示建立成功
}

db.emp.ensureIndex({empno:1,deptno:1}) #建立组合索引
db.emp.ensureIndex({empno:1},{unique:true}) #建立唯一性索引
db.emp.getIndexes()
[
{
“v” : 1,
“key” : {
“_id” : 1
},
“name” : “id”,
“ns” : “test.emp”
},
{
“v” : 1,
“key” : {
“empno” : 1
},
“name” : “empno_1”,
“ns” : “test.emp”
}
]
删除索引
db.emp.dropIndex(‘empno_1’) #删除指定索引
{ “nIndexesWas” : 2, “ok” : 1 }
db.emp.dropIndexes() #删除所有索引(除默认索引外)
索引的总大小
db.emp.totalIndexSize() #查看索引的总大小(字节数)
16352

四、用户管理

[root@node3 ~]# mongo scott
MongoDB shell version: 2.6.4
connecting to: scott

show users
show roles
建立用户
db.createUser({user:“scott”,pwd:“tiger”,roles:[{role:“userAdmin”,db:“scott”}]}) #建立用户
db.createUser({user:“root”,pwd:“root”,roles:[“root”]}) #创建超级管理员用户
用户连接数据库
[root@node3 ~]# mongo scott -u scott -p tiger
MongoDB shell version: 2.6.4
connecting to: scott

[root@node3 ~]# mongo admin -u root -p root
设置安全认证
1.auth
[root@node3 ~]# service mongod stop
[root@node3 ~]# vi /etc/mongod.conf
#auth=true
auth=true
[root@node3 ~]# service mongod start
[root@node3 ~]# mongo admin
MongoDB shell version: 2.6.4
connecting to: admin

show dbs #已经生效
2019-01-21T23:00:19.213-0800 listDatabases failed:{
“ok” : 0,
“errmsg” : “not authorized on admin to execute command { listDatabases: 1.0 }”,
“code” : 13
} at src/mongo/shell/mongo.js:47
db.auth(‘root’,‘root’) #对用户root密码为root的用户授权,1表示成功,前面已建root
1
show dbs #可以正常查看修改数据库、表等
admin 0.078GB
local 0.078GB
test 0.078GB
取消安全认证
[root@node3 ~]# vi /etc/mongod.conf
#auth=true
[root@node3 ~]# service mongod restart
2.key
[root@node3 ~]# echo “aaaaaa”>/etc/monkey #大于等于6个随便的字符串
[root@node3 ~]# chmod 600 /etc/monkey
[root@node3 ~]# chown mongod:mongod /etc/monkey
[root@node3 ~]# vi /etc/mongod.conf
keyFile=/etc/monkey
[root@node3 mongo]# service mongod restart

五、mongoDB高可用复制

详细原理见《mongodb手册中文参考版.pdf》 pg131
在这里插入图片描述
在这里插入图片描述
MongoDB高可用分两种:
Master-Slave主从复制(不推荐):
只需要在某一个服务启动时加上–master参数,而另一个服务加上—slave与—source参数,即可实现同步。MongoDB的最新版本以不在推荐此方案。
环境: redhat6.4 node3 192.168.0.5 mongodb2.6 master
redhat6.4 node4 192.168.0.6 mongodb2.6 slave
redhat6.4 node5 192.168.0.7 mongodb2.6 slave #备用,缺点:salve>1个是发生主备切换,不知选哪个作为主
Master配置
#service mongod stop
#mkdir /var/mdb #数据文件存放目录
#mongod --dbpath /var/mdb --master --fork --syslog
[root@node3 mdb]# netstat -anlp|grep mongod
tcp 0 0 0.0.0.0:27017 0.0.0.0:* LISTEN 23185/mongod
unix 2 [ ACC ] STREAM LISTENING 282382 23185/mongod /tmp/mongodb-27017.sock
unix 2 [ ] DGRAM 282344 23185/mongod

[root@node3 mdb]# mongo
MongoDB shell version: 2.6.4
connecting to: test

rs.status
function () { return db._adminCommand(“replSetGetStatus”); }
rs.help
rs.printReplicationInfo() #可以看到复制进程已启动
configured oplog size: 990MB #日志大小
log length start to end: 234secs (0.07hrs)
oplog first event time: Tue Jan 22 2019 00:38:44 GMT-0800 (PST) #第一次抽取日志时间
oplog last event time: Tue Jan 22 2019 00:42:38 GMT-0800 (PST) #最后一次抽取日志时间
now: Tue Jan 22 2019 00:42:41 GMT-0800 (PST) #当前抽取日志时间

rs.isMaster()
{
“ismaster” : ftrue, #slave为false
“maxBsonObjectSize” : 16777216,
“maxMessageSizeBytes” : 48000000,
“maxWriteBatchSize” : 1000,
“localTime” : ISODate(“2019-01-22T08:58:49.253Z”),
“maxWireVersion” : 2,
“minWireVersion” : 0,
“ok” : 1 #表示状态正常
}
slave配置
#mkdir /var/mdb
#mongod --dbpath /var/mdb --slave --source 192.168.0.5:27017 --syslog --fork
#自动将主上的数据同步过来 192.168.0.5:2701master上的IP和监听号,如果启动时间过长,需要杀掉进程重新启动

rs.isMaster()
{
“ismaster” : false, #主为true
“maxBsonObjectSize” : 16777216,
“maxMessageSizeBytes” : 48000000,
“maxWriteBatchSize” : 1000,
“localTime” : ISODate(“2019-01-22T08:58:49.253Z”),
“maxWireVersion” : 2,
“minWireVersion” : 0,
“ok” : 1 #表示状态正常
}
检查状态
rs.printReplicationInfo() #也可通过此方法查状态
this is a slave, printing slave replication info.
source: 192.168.0.5:27017
syncedTo: Tue Jan 22 2019 00:59:28 GMT-0800 (PST)
115 secs (0.03 hrs) behind the primary
或> rs.printSlaveReplicationInfo()
db.printReplicationInfo()

测试:略

设置只有key的用户可进行复制(主从都做)
1停掉服务

use admin
switched to db admin
db.shutdownServer()
2配置key文件
#echo “aaaaaa”>/etc/monkey #大于等于6个随便的字符串
#chmod 600 /etc/monkey
#chown mongod:mongod /etc/monkey
#mongod --dbpath /var/mdb --master --fork --syslog --keyFile /etc/monkey #master启动
#mongod --dbpath /var/mdb --slave --source 192.168.0.5:27017 --syslog --fork --keyFile /etc/monkey #slave启动
rs.isMaster()
rs.printReplicationInfo()
主从切换(手动)
1.关掉主服务
root@node3 ~]# ps -ef|grep mongod
root 24299 1 0 01:41 ? 00:00:05 mongod --dbpath /var/mdb --master --fork --syslog --keyFile /etc/monkey
root 24561 17738 0 01:55 pts/4 00:00:00 grep mongod
[root@node3 ~]# kill -9 24299
2.将一个slave变为master
两个slave都停掉
use admin
switched to db admin
db.shutdownServer()
[root@node4 mongoDB]# mongod --dbpath /var/mdb --master --fork --syslog --keyFile /etc/monkey #变为master
[root@node5 mongoDB]# mongod --dbpath /var/mdb --slave --source 192.168.0.6:27017 --syslog --fork --keyFile /etc/monkey #IP指向node4 ,如果进程会掉,需要备份/删掉/var/mdb下的文件
rs.isMaster()
rs.printReplicationInfo()
缺点:不能自动切换,读写分离需要指定,全量拷贝,扩容不方便,所以不推荐
Replica Sets复制集:
环境: redhat6.4 node3 192.168.0.5 mongodb2.6 master
redhat6.4 node4 192.168.0.6 mongodb2.6 slave
redhat6.4 node5 192.168.0.7 mongodb2.6 slave
配置(1-2步是所有节点配置):
1配置复制集参数
root@node3 ~]# tail -2 /etc/mongod.conf
replSet=set1 #定义个名字
keyFile=/etc/monkey
2启动(两种方式)
[root@node3 ~]# mongod -f /etc/mongod.conf
[root@node3 mdb]# mongod --dbpath /var/mdb --replSet set1 --syslog --fork #不用配置文件直接加参数启动
3配置复制集
master:
[root@node3 ~]# mongo admin
MongoDB shell version: 2.6.4
connecting to: admin
config_set1 ={_id:“set1”,members:[{_id:0,host:“192.168.0.5:27017”}]}
rs.initiate(config_set1)
set1:PRIMARY> rs.add(“192.168.0.6:27017”); #增加复制复制节点
set1:PRIMARY> rs.add(“192.168.0.7:27017”); #rs.remove((“192.168.0.7:27017”);删除用remove
set1:PRIMARY> rs.status()
set1:PRIMARY> rs.isMaster()
set1:PRIMARY> rs.printSlaveReplicationInfo()
Slave:
[root@node5 mdb]# mongo admin
MongoDB shell version: 2.6.4
connecting to: admin
set1:STARTUP2> #正在同步和初始化
set1:RECOVERING> #正在同步和初始化
set1:SECONDARY> #成为slave

4主备切换验证:
杀掉master,观察其他节点状态,通常按添加ip地址先后顺序变为master
自动完成主从主从切换,读写分离,当前无法实现读

5设置读写分离
slave设置
set1:SECONDARY> show dbs
admin (empty)
local 1.078GB
set1:SECONDARY> show collections
2019-01-23T21:31:24.786-0800 error: { “$err” : “not master and slaveOk=false”, “code” : 13435 } at src/mongo/shell/query.js:131
set1:SECONDARY> rs.slaveOk() #执行此命令后可以查询了

验证:主库插入数据,观察备库变化。略

set1:SECONDARY> use local
set1:SECONDARY> db.system.replset.find() #查看具体有哪些成员

六、MongoDB分片(区)技术

架构详细参考《mongodb手册中文参考版.pdf》 p186
在这里插入图片描述
shard集群由以下几个组件:shard,query routers和config server
Shard:用来存储数据。提供高可用和数据一致性,在生产环境下一个shard是一个复制集。
Query Routers:或者mongos实例,是客户端的接口然后在合适的shard中操作然后返回数据,对于shard集群可以包含多余一个router来分流客户端请求。一个客户端发送请求到一个router,大多数shard集群有很多query router。
Config Server:保存集群元数据,query router 根据config server上的元数据来决定路由到哪个shard。
分区分为keys、range和hash分区
一)简单分片(不能容灾)
环境:
Readhat6.4 MongoDB2.6.4
192.168.0.5 node3 config route shared server
192.168.0.6 node4 192.168.0.7 node5 shared 分片数据 业务数据

1)192.168.0.5 Config server配置
1-3步只在192.168.0.5上做
1配置三个,1个只在test环境中使用
#mkdir -pv /var/{mdb1,mdb2,mdb3}
#mongod --dbpath /var/mdb1 --port 28001 --logpath /var/log/mongodb/mdb1.log --logappend --fork --configsvr
#mongod --dbpath /var/mdb2 --port 28002 --logpath /var/log/mongodb/mdb2.log --logappend --fork --configsvr
#mongod --dbpath /var/mdb3 --port 28003 --logpath /var/log/mongodb/mdb3.log --logappend --fork --configsvr

或可以放在配置文件里
#vi /etc/mdb1.conf #mdb2.conf mdb3.conf
dbpath =/var/mdb1 #mdb2 mdb3
port =28001 #28002 28003
logpath =/var/log/mongodb/mdb1.log #mdb2.log mdb3.log
logappend=true
fork=true
configsvr=true #config服务器
mongod -f /etc/mdb1.conf

#mongos --port 28000 --configdb 192.168.0.5:28001,192.168.0.5:28002,192.168.0.5:28003
–logpath /var/log/mongodb/mongos.log --logappend --fork

或下面的方式
#vi/etc/route.conf
port=28000
configdb=192.168.0.5:28001,192.168.0.5:28002,192.168.0.5:28003
logpath=/var/log/mongodb/mongos.log
logappend=true
fork=true
#mongos -f /etc/route.conf

3检查进程
netstat -tlnp|grep mongo
2)shard配置
1.分片服务器(三个节点操作相同)
#mkdir /data/data1
mongod --port 27020 --dbpath /data/data1 --logpath /var/log/mongodb/shared1.log --fork --shardsvr

或以下方式
#vi /etc/shard1.conf
port=27020
dbpath=/data/data1
logpath=/var/log/mongodb/shared1.log
fork=true
shardsvr=true

mongod -f /etc/shard1.conf
2.增加shard服务器
[root@node3 data]# mongo 192.168.0.5:28000
mongos> use admin
mongos> db.runCommand({addshard:“192.168.0.5:27020”,allowLocal:true})
#本地加llowLocal:true
mongos> db.runCommand({addshard:“192.168.0.6:27020”})
mongos> db.runCommand({addshard:“192.168.0.7:27020”})
3.查找分片信息(3个)
数据能够存放到3个分片中
mongos> use config
switched to db config
mongos> db.shards.find()
{ “_id” : “shard0000”, “host” : “192.168.0.5:27020” }
{ “_id” : “shard0001”, “host” : “192.168.0.6:27020” }
{ “_id” : “shard0002”, “host” : “192.168.0.7:27020” }

4.test
mongos> use test
mongos> db.dept.insert({“name”:“wang”,age:29})

admin (empty)
config 0.016GB
test 0.078GB
启用分片功能
mongos> use admin
mongos> db.runCommand({“enablesharding”:“test”})
mongos> db.runCommand({“shardcollection”:“test.dept”,“key”:{"_id":1}}) #“_id:1”代表启用range分片

检查(true表示启用分片,在shard0000上)
mongos> db.databases.find()
{ “_id” : “admin”, “partitioned” : false, “primary” : “config” }
{ “_id” : “test”, “partitioned” : true, “primary” : “shard0000” }
{ “_id” : “wyzc”, “partitioned” : true, “primary” : “shard0001” }

mongos> sh.status() #查看详细的分片信息

插入一些数据后,可以看到启用了其它分片
mongos> use config
mongos> db.chunks.find()
{ “_id” : “test.dept-_id_MinKey”, “lastmod” : Timestamp(2, 0), “lastmodEpoch” : ObjectId(“5c4aac12753043457d1fd323”), “ns” : “test.dept”, “min” : { “_id” : { “KaTeX parse error: Expected 'EOF', got '}' at position 13: minKey" : 1 }̲ }, "max" : { "…maxKey” : 1 } }, “shard” : “shard0000” }

因为还未配置复制功能,当停掉shard0000的服务器是,查询数据会报错。再次启动变为正常,还不安全
mongos> db.dept.find()
error: {
“$err” : “socket exception [CONNECT_ERROR] for 192.168.0.6:27020”,
“code” : 11002,
“shard” : “shard0001”

二)分片数据需要容灾 —复制 副本集 replSet(推荐)
环境(3个分片,3个主从和仲裁,实现分片和容灾)
Readhat6.4 MongoDB2.6.4
在这里插入图片描述
将原有mongo进程全部干掉
#mkdir -pv /var/mdb{1,2,3}
#mkdir /data/data1

192.168.0.5上

1.分片
#vi /etc/mdb1.conf
directoryperdb=true
dbpath =/var/mdb1
port =27018
logpath =/var/log/mongodb/mdb1.log
logappend=true
pidfilepath=/var/run/mongodb/mongod1.pid
fork=true
replSet=set1
shardsvr=true
[root@node3 data]# vi /etc/mdb2.conf
directoryperdb=true
dbpath =/var/mdb2
port =27019
logpath =/var/log/mongodb/mdb2.log
logappend=true
pidfilepath=/var/run/mongodb/mongod2.pid
fork=true
replSet=set2
shardsvr=true
[root@node3 data]# vi /etc/mdb3.conf
directoryperdb=true
dbpath =/var/mdb3
port =27020
logpath =/var/log/mongodb/mdb3.log
logappend=true
pidfilepath=/var/run/mongodb/mongod3.pid
fork=true
replSet=set3
shardsvr=true

2.config
[root@node3 data]# vi /etc/mongodc.conf
dbpath =/data/data1
port =28000
directoryperdb=true
logpath =/var/log/mongodb/config.log
logappend=true
fork=true
configsvr=true #config服务器
pidfilepath=/var/run/mongodb/mongodc.pid

3.route
[root@node3 data]# vi /etc/mongodr.conf
port=27017
configdb=192.168.0.5:28000,192.168.0.6:28000,192.168.0.7:28000
logpath=/var/log/mongodb/route.log
logappend=true
fork=true
pidfilepath=/var/run/mongodb/mongodr.pid
chunkSize=6

将配置文件拷到其它主机
[root@node3 etc]# scp -r mdb* mongod* 192.168.0.6:/etc/
[root@node3 etc]# scp -r mdb* mongod* 192.168.0.7:/etc/

起配置文件
[root@node3 mongo]# mongod -f /etc/mongodc.conf
[root@node4 data1]# mongod -f /etc/mongodc.conf
[root@node5 data1]# mongod -f /etc/mongodc.conf

起路由文件(如果起不来可能是时间不同步)
[root@node3 etc]# mongos -f /etc/mongodr.conf
[root@node4 data1]# mongos -f /etc/mongodr.conf
[root@node5 data1]# mongos -f /etc/mongodr.conf

起分片(三个节点)
[root@node3 mongodb]# mongod -f /etc/mdb1.conf
[root@node3 mongodb]# mongod -f /etc/mdb2.conf
[root@node3 mongodb]# mongod -f /etc/mdb3.conf

五个进程
[root@node4 data1]# netstat -anlp|grep mongo
tcp 0 0 0.0.0.0:27019 0.0.0.0:* LISTEN 3147/mongod
tcp 0 0 0.0.0.0:27020 0.0.0.0:* LISTEN 3193/mongod
tcp 0 0 0.0.0.0:28000 0.0.0.0:* LISTEN 3007/mongod
tcp 0 0 0.0.0.0:27017 0.0.0.0:* LISTEN 3038/mongos
tcp 0 0 0.0.0.0:27018 0.0.0.0:* LISTEN 3101/mongod

4.配置副本集
port:27018配置副本集
确认端口
[root@node4 ~]# grep replSet /etc/mdb1.conf
replSet=set1
[root@node4 ~]# grep port /etc/mdb1.conf
port=27018

[root@node3 mongodb]# mongo 192.168.0.5:27018
MongoDB shell version: 2.6.4
connecting to: 192.168.0.5:27018/test

use admin
config_set1 ={_id:“set1”,members:[{_id:0,host:“192.168.0.5:27018”,priority:2},{_id:1,host:“192.168.0.6:27018”},{_id:2,host:“192.168.0.7:27018”,arbiterOnly:true}]}
rs.initiate(config_set1)
rs.status()

port:27019配置副本集
[root@node3 mdb1]# mongo 192.168.0.5:27019

use admin
config_set2 ={_id:“set2”,members:[{_id:0,host:“192.168.0.5:27019”,arbiterOnly:true},{_id:1,host:“192.168.0.6:27019”,priority:2},{_id:2,host:“192.168.0.7:27019”}]}
rs.initiate(config_set2)
rs.status()

port:27020配置副本集
[root@node3 mdb1]# mongo 192.168.0.5:27020

use admin
config_set3 ={_id:“set3”,members:[{_id:0,host:“192.168.0.5:27020”},{_id:1,host:“192.168.0.6:27020”,arbiterOnly:true},{_id:2,host:“192.168.0.7:27020”,priority:2}]}
rs.initiate(config_set3)
rs.status()

5.Route:
[root@node3 ~]# mongo 192.168.0.5:27017
MongoDB shell version: 2.6.4
connecting to: 192.168.0.5:27017/test
mongos> use admin
switched to db admin
mongos> db.runCommand({addshard:“set1/192.168.0.5:27018,192.168.0.6:27018,192.168.0.7:27018”})
mongos> db.runCommand({addshard:“set2/192.168.0.5:27019,192.168.0.6:27019,192.168.0.7:27019”})
mongos> db.runCommand({addshard:“set3/192.168.0.5:27020,192.168.0.6:27020,192.168.0.7:27020”})

6.启用分区(eg)
mongos> db.runCommand({enablesharding:“test”})
{ “ok” : 1 }
mongos> db.runCommand({enablesharding:“wyzc”})
{ “ok” : 1 }
mongos> db.runCommand({shardcollection:“test.com”,key:{id:“hashed”}}) #hash分区
mongos> db.runCommand({shardcollection:“wyzc.com”,key:{id:1}}) #range分区

7.测试:
[root@node4 ~]# mongo 27017
mongos> use test
mongos> for(var i=1;i<=200000;i++){db.com.insert({id:i,job:“dba”})}

mongos> use config
switched to db config
mongos> db.chunks.find()
mongos> sh.status()
mongos> db.shards.find() #查看hash分区的信息
切库测试略
三)管理维护sharding
#mongo 27017

use admin
db.runCommand({listshards:1}) #列出所有的shard server
printShardingStatus() #查看sharding信息
db.runCommand({isdbgrid:1}) #判断是否是sharding
s> db.test.com.stats() #查看是否被分区
“sharded” : false,

七、性能监控

《MongoDB_权威指南_中文版.pdf》 pg58
#mongosniff —source NET lo
此工具可以从底层监控到底有那些命令发送给了MongoDB去执行,从中就可以进行分析

#mongostat
insert query update delete getmore command vsize res faults netIn netOut conn repl time
0 0 0 0 0 1 325m 8m 0 62b 721b 2 RTR 21:18:55
0 0 0 0 0 1 325m 8m 0 62b 721b 2 RTR 21:18:56
8 0 0 0 0 9 325m 8m 0 1k 1k 2 RTR 21:18:57
124 0 0 0 0 124 325m 8m 0 16k 7k 2 RTR 21:18:58
此工具可以快速的查看某组运行中的MongoDB实例的统计信息,每秒刷新一次
字段说明:
Inert:每秒插入量
query:每秒查询量
update:每秒更新量
Delete:每秒删除量
Locked:锁定量
Qr|qw:客户端查询排队长度(读|写)
Ar|aw:活跃客户端量(读|写)
Conn:连接数
Time:当前时间

db.serverStatus() #最常用也是最基础的查看实例运行状态的命令之一

db.stats() #查看数据库状态信息。

八、管理篇

可参考《MongoDB_权限指南_中文版.pdf》
1.GridFS(导入导出文件)
files包含元数据对象
chunks包含其他一些相关信息的二进制块
任何默认的GridFs存储将包括名目空间fs.files和fs.chunks。各种第三方语言的驱动有权限更改这个前缀。

数据入库
mongofiles是从命令行操作的GridFS的一种工具,将一个文件存放到库中
#mongofiles put testfile #testfile是当前具体的文件名
#mongofiles put mongodb-org-server-2.6.4-1.x86_64.rpm
connected to: 127.0.0.1
added file: { _id: ObjectId(‘5c4979096c7efdbe5ac84208’), filename: “mongodb-org-server-2.6.4-1.x86_64.rpm”, chunkSize: 261120, uploadDate: new Date(1548319018939), md5: “650ef426b6e6036916688abcc0d3c141”, length: 9440807 }
done!

查看有哪些GridFS文件
[root@node5 mongoDB]# mongofiles list
connected to: 127.0.0.1
mongodb-org-server-2.6.4-1.x86_64.rpm 9440807

进库查看
[root@node5 mongoDB]# mongo
MongoDB shell version: 2.6.4
connecting to: test

show collections
dept
fs.chunks
fs.files
system.indexes
system.js
things
db.fs.files.find()
{ “_id” : ObjectId(“5c4979096c7efdbe5ac84208”), “filename” : “mongodb-org-server-2.6.4-1.x86_64.rpm”, “chunkSize” : 261120, “uploadDate” : ISODate(“2019-01-24T08:36:58.939Z”), “md5” : “650ef426b6e6036916688abcc0d3c141”, “length” : 9440807 }
字段说明:
Filename:存储的文件名
chunkSize:chunks分块的大小
UploadDate:入库时间
Md5:此文件的md5码
Length:文件大小,单位“字节”
存储的是一些基础的元数据信息
db.fs.chunks.find()
{ “_id” : ObjectId(“5c49790a360edda804261d55”), “files_id” : ObjectId(“5c4979096c7efdbe5ac84208”), “n” : 0, “data” : BinData(0,"7avu2wMAAAAAAW1vbmdvZGItb3JnLXNlcnZlci0yLjYuNC0xAAAAAAAAAAAAAAAAAAAA
字段“n”代表的是chunks的序号,此序号从0开始,,fs.chunks存储的是一些实际的内容数据信息

数据出库
#mongofiles get testfile #testfile是当前具体的文件名
#mongofiles get mongodb-org-server-2.6.4-1.x86_64.rpm
connected to: 127.0.0.1
done write to: mongodb-org-server-2.6.4-1.x86_64.rpm

#md5sum mongodb-org-server-2.6.4-1.x86_64.rpm # 校验md5,结果跟库里相同
650ef426b6e6036916688abcc0d3c141 mongodb-org-server-2.6.4-1.x86_64.rpm

2.数据导出mongoexport
1)常用导出方法
[root@node5 installation]# mongoexport -d test -c dept -o dept.dat
connected to: 127.0.0.1
exported 4 records
[root@node5 installation]# cat dept.dat
{ “_id” : { “KaTeX parse error: Expected 'EOF', got '}' at position 35: …8e6266824c3db" }̲, "deptno" : 10…oid” : “5c494eeea678e6266824c3dc” }, “deptno” : 20, “dname” : “RESEARCH”, “loc” : “DALLAS” }
{ “_id” : { “KaTeX parse error: Expected 'EOF', got '}' at position 35: …8e6266824c3dd" }̲, "deptno" : 30…oid” : “5c494eefa678e6266824c3de” }, “deptno” : 40, “dname” : “OPERATIONS”, “loc” : “BOSTON” }
参数说明:
-d:指明使用的库,本例”test”
-c指明要导出的表,本例“dept”
-o指明要导出的文件名,本例”dept.dat”
从上面可以看到导出的方式使用的是JSON的样式

2)导出CSV格式的文件
[root@node5 installation]# mongoexport -d test -c dept --csv -f deptno,dname,loc -o dept_csv.dat
connected to: 127.0.0.1
exported 4 records
[root@node5 installation]# cat dept_csv.dat
deptno,dname,loc
10.0,“ACCOUNTING”,“NEW YORK”
20.0,“RESEARCH”,“DALLAS”
30.0,“SALES”,“CHICAGO”
40.0,“OPERATIONS”,“BOSTON”
-csv指要导出为csv格式
-f 指明需要导出那些列
3.数据导入mongoimport

db.dept.drop() #删除原表
[root@node5 installation]# mongoimport -d test -c dept dept.dat #导入
connected to: 127.0.0.1
2019-01-24T01:48:58.860-0800 imported 4 objects

db.dept.drop() #删除原表
#mongoimport -d test -c dept --type csv --headerline --file dept_csv.dat
connected to: 127.0.0.1
2019-01-24T02:02:55.439-0800 imported 4 objects
参数说明:
-type指明要导入的文件格式
-headerline指明不导入第一行,因为第一行是列名
-file指明要导入的文件路径
注:CSV格式良好,主流数据库都支持导出为CSV的格式,这种格式非常利于异构数据迁移。
4.数据备份mongodump
#mongodump -d test #会自动创建一个dump目录
#mongodump -d test -o my_dump #指定my_dump目录存放备份
5.数据恢复mongorestore
use test

db.dropDatabase() #删除库做测试
show dbs
#mongorestore -d test my_dump/*
#也可不删除test库,指明-drop参数,就可以在恢复的时候先删除表再向表中插入数据

6.访问安全控制、执行计划略(见上面章节或参考书籍)

MongoDB shell使用
set1:PRIMARY> for(var i=1;i<10;i++) db.things.save({x:4,j:i});
set1:PRIMARY> db.things.find()
{ “_id” : ObjectId(“5c4952aaa678e6266824c3df”), “x” : 4, “j” : 1 }
{ “_id” : ObjectId(“5c4952aaa678e6266824c3e0”), “x” : 4, “j” : 2 }
{ “_id” : ObjectId(“5c4952aaa678e6266824c3e1”), “x” : 4, “j” : 3 }
{ “_id” : ObjectId(“5c4952aaa678e6266824c3e2”), “x” : 4, “j” : 4 }
{ “_id” : ObjectId(“5c4952aaa678e6266824c3e3”), “x” : 4, “j” : 5 }
#如果还有没显示的,用it继续查看
set1:PRIMARY> it
no cursor
set1:PRIMARY> var cursor=db.things.find();
set1:PRIMARY> while(cursor.hasNext()) printjson(cursor.next());
{ “_id” : ObjectId(“5c4952aaa678e6266824c3df”), “x” : 4, “j” : 1 }
{ “_id” : ObjectId(“5c4952aaa678e6266824c3e0”), “x” : 4, “j” : 2 }
{ “_id” : ObjectId(“5c4952aaa678e6266824c3e1”), “x” : 4, “j” : 3 }
…………
#上面的例子显示了游标风格的迭代输出,hasNext()的函数告诉我们是否还有数据,如果有可以调用next()函数。
set1:PRIMARY> db.things.find().forEach(printjson);

可以把游标当作数组来用:
set1:PRIMARY> var cursor=db.things.find()
set1:PRIMARY> printjson(cursor[4])
{ “_id” : ObjectId(“5c4952aaa678e6266824c3e3”), “x” : 4, “j” : 5 }

为防止很大的游标对象占用内存导致内存溢出,用迭代的方式把游标转换成真实的数组类型输出:
set1:PRIMARY> var arr=db.things.find().toArray()
set1:PRIMARY> arr[5]
{ “_id” : ObjectId(“5c4952aaa678e6266824c3e4”), “x” : 4, “j” : 6 }

九、存储过程

实际是用javascript写的

Eg:

function addNumbers(x,y){return x + y;}

将sql自定义函数转换为MongoDB的存储过程:

db.system.js.save({_id:“addNumbers”,value:function(x,y){return x + y;}})
WriteResult({ “nMatched” : 0, “nUpserted” : 1, “nModified” : 0, “_id” : “addNumbers” })

存储过程可以被查看,修改和删除:

db.system.js.find()
{ “_id” : “addNumbers”, “value” : function (x,y){return x + y;} }

调用存储过程

db.eval(‘addNumbers(3,4.2)’)
7.2

直接调用算数运算

db.eval(function(){return 3+3;})
6

取出某张表的数据量

db.system.js.save({_id:“get_count”,value:function(){return db.dept.count();}})
WriteResult({ “nMatched” : 0, “nUpserted” : 1, “nModified” : 0, “_id” : “get_count” })
db.eval(“get_count()”)
4

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值