NoSQL(NoSQL = Not Only SQL ),意即」不只僅是SQL」。html
在現代的計算系統上天天網絡上都會產生龐大的數據量。linux
這些數據有很大一部分是由關係數據庫管理系統(RDMBSs)來處理。 1970年 E.F.Codd’s提出的關係模型的論文 「A relational model of data for large shared data banks」,這使得數據建模和應用程序編程更加簡單。git
經過應用實踐證實,關係模型是很是適合於客戶服務器編程,遠遠超出預期的利益,今天它是結構化數據存儲在網絡和商務應用的主導技術。正則表達式
NoSQL 是一項全新的數據庫革命性運動,早期就有人提出,發展至2009年趨勢愈加高漲。NoSQL的擁護者們提倡運用非關係型的數據存儲,相對於鋪天蓋地的關係型數據庫運用,這一律念無疑是一種全新的思惟的注入。sql
NoSQL,指的是非關係型的數據庫。NoSQL有時也稱做Not Only SQL的縮寫,是對不一樣於傳統的關係型數據庫的數據庫管理系統的統稱。
對NoSQL最廣泛的解釋是」非關聯型的」,強調Key-Value Stores和文檔數據庫的優勢,而不是單純的反對RDBMS。
NoSQL用於超大規模數據的存儲。(例如谷歌或Facebook天天爲他們的用戶收集萬億比特的數據)。這些類型的數據存儲不須要固定的模式,無需多餘操做就能夠橫向擴展。mongodb
今天咱們能夠經過第三方平臺(如:Google,Facebook等)能夠很容易的訪問和抓取數據。用戶的我的信息,社交網絡,地理位置,用戶生成的數據和用戶操做日誌已經成倍的增長。咱們若是要對這些用戶數據進行挖掘,那SQL數據庫已經不適合這些應用了, NoSQL數據庫的發展也卻能很好的處理這些大的數據。shell
Mongodb由C++語言編寫的,是一個基於分佈式文件存儲的開源數據庫系統。,是專爲可擴展性,高性能和高可用性而設計的數據庫, 是非關係型數據庫中功能最豐富,最像關係型數據庫的,它支持的數據結構很是散,是相似 json 的 bjson 格式,所以能夠存儲比較複雜的數據類型。數據庫
MongoDB的(來自於英文單詞「了Humongous」,中文含義爲「龐大」)是能夠應用於各類規模的企業,各個行業以及各種應用程序的開源數據庫。做爲一個適用於敏捷開發的數據庫,MongoDB的的數據模式能夠隨着應用程序的發展而靈活地更新。編程
MongoDB 以一種叫作 BSON(二進制 JSON)的存儲形式將數據做爲文檔存儲
。具備類似結構的文檔一般被整理成集合
。能夠把這些集合當作相似於關係數據庫中的表
: 文檔和行類似, 字段和列類似。json
JSON(JavaScript Object Notation) 是一種輕量級的數據交換格式。 JSON採用徹底獨立於語言的文本格式,可是也使用了相似於C語言家族的習慣(包括C、 C++、 C#、 Java、JavaScript、 Perl、 Python等)。這些特性使JSON成爲理想的數據交換語言。 易於人閱讀和編寫,同時也易於機器解析和生成(通常用於提高網絡傳輸速率)。JSON 的官方 MIME 類型是 application/json,文件擴展名是 .json。
MongoDB 使用JSON(JavaScript ObjectNotation)文檔存儲記錄。
JSON簡單說就是JavaScript中的對象和數組,經過對象和數組能夠表示各類複雜的結構。
對象:
對象在js中表示爲「{}」括起來的內容,數據結構爲 {key: value,key: value,…}的鍵值對的
結構,在面向對象的語言中, key爲對象的屬性, value爲對應的屬性值,因此很容易理
解,取值方法爲 對象.key 獲取屬性值,這個屬性值的類型能夠是 數字、字符串、數組、
對象幾種。
例如: {"FirstName":"ke","LastName":"me","email":"hikeme@aa"}
取值方式和全部語言中同樣,使用key獲取,字段值的類型能夠是 數字、字符串、數組、對象幾種。
BSON是一種類JSON的一種二進制形式的存儲格式
,簡稱Binary JSON,它和JSON同樣,支持內嵌的文檔對象和數組對象,可是BSON有JSON沒有的一些數據類型,如Date和BinData類型。
它的優勢是靈活性高,但它的缺點是空間利用率不是很理想。
BSON有三個特色:輕量性、可遍歷性、高效性。
對JSON來講,數據存儲是無類型的,好比你要修改基本一個值,從9到10,因爲從一個字符變成了兩個,因此可能其後面的全部內容都須要日後移一位才能夠。而使用BSON,你能夠指定這個列爲數字列,那麼不管數字從9長到10仍是100,咱們都只是在存儲數字的那一位上進行修改,不會致使數據總長變大。固然,在MongoDB中,若是數字從整形增大到長整型,仍是會致使數據總長變大的。
有時BSON相對JSON來講也並無空間上的優點,好比對{「sex」:1},在JSON的存儲上
1只使用了一個字節,而若是用BSON,那就是至少4個字節
高性能: Mongodb 提供高性能的數據持久性,尤爲是支持嵌入式數據模型減小數據庫系統上的 I/O操做,索引支持能快的查詢,而且能夠包括來嵌入式文檔和數組中的鍵
豐富的語言查詢: Mongodb 支持豐富的查詢語言來支持讀寫操做(CRUD)以及數據彙總,文本搜索和地理空間索引
高可用性: Mongodb 的複製工具,成爲副本集,提供自動故障轉移和數據冗餘,
水平可擴展性: Mongodb 提供了可擴展性,做爲其核心功能的一部分,分片是將數據分,在一組計算機上。
支持多種存儲引擎: WiredTiger 存儲引擎和、 MMAPv1存儲引擎和 InMemory 存儲引擎
MongoDB Server
是一個文檔數據庫,具備您須要的可擴展性和靈活性,豐富的查詢和索引,
當前最高穩定版本4.0
MongoDB Drivers
官方MongoDB客戶端庫提供C, C ++, C#, Java, Node.JS, Perl, PHP,Python, Ruby和Scala驅動程序的參考指南。
MongoDB Stitch
爲開發人員提供了一個API到MongoDB和其餘後端服務。保持MongoDB的所有功能和靈性,同時受益於強大的系統來配置細粒度的數據訪問控制。
MongoDB Atlas
MongoDB在雲中部署,操做和擴展的最佳方式。適用於AWS,Azure和Google Cloud Platform。輕鬆將數據遷移到MongoDB Atlas,零停機
MongoDB Cloud Manager
是一個用於管理MongoDB部署的軟件包。 Ops Manager提供Ops Manager監控和Ops Manager備份,可幫助用戶優化羣集並下降操做風險
MongoDB Charts
能夠最快速最簡單的建立Mongodb可視化圖表
MongoDB Connector for BI
MongoDB商業智能鏈接器(BI)容許用戶使用SQL建立查詢,並使用現有的關係商業智能工具(如Tableau, MicroStrategy和Qlik)對其MongoDB Enterprise數據進行可視化,圖形化和報告。
MongoDB Compass
經過從集合中隨機抽樣一個文檔子集,爲用戶提供其MongoDB模式的圖形視圖。採樣文件可最大程度地下降對數據庫的影響,並能快速產生結果。有關 抽樣的更多信息
MongoDB Spark Connector
使用鏈接器,您能夠訪問全部使用MongoDB數據集的Spark庫:用SQL進行分析的數據集(受益於自動模式推理),流式傳輸,機器學習和圖形API。您也可使用鏈接器與Spark Shell。
個人操做系統版本
[root@mongo-160 ~]# cat /etc/redhat-release CentOS Linux release 7.2.1511 (Core)
官方文檔手冊
# 官方文檔手冊 https://docs.mongodb.com/manual/
我安裝的是MongoDB 3.4 版本的,選擇3.4版本查看相應手冊
我使用的是二進制包方式
mongo軟件以軟鏈接形式放在/opt 目錄下
mongo數據存放目錄存放在/data/mongo
[root@mongo-160 ~]# mkdir -p /data/soft [root@mongo-160 ~]# cd /data/soft/ [root@mongo-160 soft]# wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-3.4.20.tgz [root@mongo-160 soft]# tar zxvf mongodb-linux-x86_64-3.4.20.tgz -C /opt/ [root@mongo-160 soft]# cd /opt/ [root@mongo-160 opt]# ln -s mongodb-linux-x86_64-3.4.20/ mongodb [root@mongo-160 opt]# ll total 0 lrwxrwxrwx. 1 root root 28 Jun 5 18:09 mongodb -> mongodb-linux-x86_64-3.4.20/ drwxr-xr-x. 3 root root 86 Jun 5 17:56 mongodb-linux-x86_64-3.4.20 # 爲何作軟連接了,之後後續版本作升級, # 能夠快速回滾到原來版本 這是最根本的 # 還能夠作多實例 # 建立數據目錄 [root@mongo-160 opt]# mkdir -p /data/mongodb [root@mongo-160 opt]# mkdir -p /opt/mongodb/{conf,logs,pid} [root@mongo-160 mongodb]# cd /opt/mongodb/ [root@mongo-160 mongodb]# ll total 120 drwxr-xr-x. 2 root root 4096 Jun 5 17:56 bin drwxr-xr-x. 2 root root 6 Jun 5 18:13 conf -rw-r--r--. 1 root root 34520 Mar 13 06:02 GNU-AGPL-3.0 drwxr-xr-x. 2 root root 6 Jun 5 18:13 logs -rw-r--r--. 1 root root 16726 Mar 13 06:02 MPL-2 drwxr-xr-x. 2 root root 6 Jun 5 18:13 pid -rw-r--r--. 1 root root 2266 Mar 13 06:02 README -rw-r--r--. 1 root root 55625 Mar 13 06:02 THIRD-PARTY-NOTICES
mongodb.conf 配置文件是yaml格式的
看看官方文檔3.4版本的配置手冊:
https://docs.mongodb.com/v3.4/reference/configuration-options/
個人環境配置文件以下:
[root@mongo-160 ~]# cat /opt/mongodb/conf/mongodb.conf systemLog: destination: file #Mongodb 日誌輸出的目的地,指定一個 file 或者 syslog,若是指定 file,必須指定systemlog.path logAppend: true #當實例重啓時,不建立新的日誌文件,在老的日誌文件末尾繼續添加 path: /opt/mongodb/logs/mongodb.log #日誌路徑 storage: dbPath: /data/mongodb #數據存儲目錄 journal: #回滾日誌 enabled: true directoryPerDB: true #默認 false,不適用 inmemory engine wiredTiger: engineConfig: cacheSizeGB: 1 #將用於全部數據緩存的最大小 directoryForIndexes: true #默認 false 索引集合 storage.dbPath 存儲在數據單獨子目錄 processManagement: #使用處理系統守護進程的控制處理 fork: true # fork and run in background 後臺運行 pidFilePath: /opt/mongodb/pid/mongod.pid # location of pidfile 建立 pid 文件 net: port: 27017 #監聽端口 bindIp: 127.0.0.1,10.0.0.160 #綁定 ip #replication: # oplogSizeMB: 1024 #複製操做日誌的大小 # replSetName: xxx #副本集名稱,同一個副本集的全部主機必須設置相同的名稱
#開啓mongo [root@mongo-160 ~]# /opt/mongodb/bin/mongod -f /opt/mongodb/conf/mongodb.conf about to fork child process, waiting until server is ready for connections. forked process: 14662 child process started successfully, parent exiting #檢查是否有mongo進程 [root@mongo-160 ~]# ps aux | grep mongo root 14662 0.9 2.1 942708 43296 ? Sl 09:51 0:00 /opt/mongodb/bin/mongod -f /opt/mongodb/conf/mongodb.conf root 14691 0.0 0.0 112644 948 pts/0 R+ 09:53 0:00 grep --color=auto mongo #檢查mongo的端口號 [root@mongo-160 ~]# netstat -ntulp | grep mongo tcp 0 0 10.0.0.160:27017 0.0.0.0:* LISTEN 14662/mongod tcp 0 0 127.0.0.1:27017 0.0.0.0:* LISTEN 14662/mongod #檢查mongo數據文件是否生成,沒生成之前默認是空的 [root@mongo-160 ~]# cd /data/mongodb/ [root@mongo-160 mongodb]# ls admin journal _mdb_catalog.wt sizeStorer.wt WiredTiger WiredTiger.lock WiredTiger.wt diagnostic.data local mongod.lock storage.bson WiredTigerLAS.wt WiredTiger.turtle #關閉mongo [root@mongo-160 mongodb]# /opt/mongodb/bin/mongod -f /opt/mongodb/conf/mongodb.conf --shutdown killing process with pid: 14662 # 再次查看還有沒有端口號,沒有了 [root@mongo-160 mongodb]# netstat -ntulp | grep mongo
注意一下: 儘可能少用kill -9
若是用kill 建議用
shell> kill -2 PID 原理:-2表示向mongod進程發送SIGINT信號。這是終端等同於ctrl+c 或 shell> kill -4 PID 原理:-4表示向mognod進程發送SIGTERM信號。 mongod進程收到SIGINT信號或者SIGTERM信號,會作一些處理 > 關閉全部打開的鏈接 > 將內存數據強制刷新到磁盤 > 當前的操做執行完畢 > 安全中止 切忌kill -9
[root@mongo-160 mongodb]# echo 'PATH=$PATH:/opt/mongodb/bin' >> /etc/profile [root@mongo-160 mongodb]# tail -n 1 /etc/profile PATH=$PATH:/opt/mongodb/bin [root@mongo-160 mongodb]# source /etc/profile #查看有哪些mongo命令,是否寫入環境變量成功了,有就是成功了 [root@mongo-160 mongodb]# mongo mongo mongodump mongofiles mongooplog mongoreplay mongos mongotop mongod mongoexport mongoimport mongoperf mongorestore mongostat
[root@mongo-160 ~]# echo "10.0.0.160 mongo-160" >> /etc/hosts [root@mongo-160 ~]# ping mongo-160 PING mongo-160 (10.0.0.160) 56(84) bytes of data. 64 bytes from mongo-160 (10.0.0.160): icmp_seq=1 ttl=64 time=0.060 ms
# 開啓mongo [root@mongo-160 ~]# mongod -f /opt/mongodb/conf/mongodb.conf # 鏈接mongo [root@mongo-160 ~]# mongo mongo-160:27017 MongoDB shell version v3.4.20 connecting to: mongodb://mongo-160:27017/test MongoDB server version: 3.4.20 Welcome to the MongoDB shell. ... > exit bye
注意,關閉命令建議使用 mongo 內置的 db.shutdownServer()
命令
使用這條命令的前提是必須使用 localhost 登錄mongo
,不然會提示報錯
[root@mongo-160 ~]# mongo localhost:27017 MongoDB shell version v3.4.20 connecting to: mongodb://localhost:27017/test MongoDB server version: 3.4.20 ... > db.shutdownServer() server should be down... 2019-06-06T10:37:38.205+0800 I NETWORK [thread1] trying reconnect to localhost:27017 (127.0.0.1) failed > exit bye [root@mongo-160 ~]# ps -ef | grep mongo root 15258 2418 0 10:39 pts/0 00:00:00 grep --color=auto mongo
** WARNING: Access control is not enabled for the database. ** Read and write access to data and configuration is unrestricted. 對數據庫來講訪問控制是沒有開啓的,讀取和寫入數據和配置是不受限制的。須要咱們建立個用戶, 開啓認證。 ** WARNING: You are running this process as the root user, which is not recommended. 不推薦以root用戶來運行mongo ** 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' 自CentOS6版本開始引入了Transparent Huge Pages(THP),從CentOS7版本開始,該特性默認就會啓用。儘管THP的本意是爲提高內存的性能,不過某些數據庫廠商仍是建議直接關閉THP(好比說Oracle、MariaDB、 MongoDB等),透明的Huge Pages可能會在運行時引發內存分配延遲。
查看THP的啓動狀態:
[root@mongo-160 ~]# cat /sys/kernel/mm/transparent_hugepage/enabled [always] madvise never [root@mongo-160 ~]# cat /sys/kernel/mm/transparent_hugepage/defrag [always] madvise never
透明的大頁(THP)是一種Linux內存管理系統,它能夠減小機器w上的翻譯後備緩衝區(TLB)查找的開銷
always - always use THP never - disable THP
運行如下命令即時禁用THP
[root@mongo-160 ~]# echo never > /sys/kernel/mm/transparent_hugepage/enabled [root@mongo-160 ~]# echo never > /sys/kernel/mm/transparent_hugepage/defrag [root@mongo-160 ~]# cat /sys/kernel/mm/transparent_hugepage/defrag always madvise [never] [root@mongo-160 ~]# cat /sys/kernel/mm/transparent_hugepage/enabled always madvise [never] [root@mongo-160 ~]# chmod +x /etc/rc.d/rc.local [root@mongo-160 ~]# vim /etc/rc.d/rc.local #添加以下兩行內容 echo never > /sys/kernel/mm/transparent_hugepage/enabled echo never > /sys/kernel/mm/transparent_hugepage/defrag [root@mongo-160 ~]# tail -n 2 /etc/rc.d/rc.local echo never > /sys/kernel/mm/transparent_hugepage/enabled echo never > /sys/kernel/mm/transparent_hugepage/defrag
CRUD 操做是 create(建立), read(讀取), update(更新)和 delete(刪除) 文檔
MongoDB 3.x 不支持多文檔事務(mongodb4.0 開始支持 )。可是 MongoDB 確實在一個文檔上提供了原子操做。儘管集合中的文檔一般都是相同的,可是 MongoDB 中的集合不須要指定 schema。
MongoDB 不支持 SQL 可是支持本身的豐富的查詢語言。
在 MongoDB 中,存儲在集合中的每一個文檔都須要一個惟一的 _id 字段,做爲主鍵。若是插入的文檔省略了該_id 字段,則 MongoDB 驅動程序將自動爲該字段生成一個 ObjectId_id。也用於經過更新操做插入的文檔upsert: true.若是文檔包含一個_id 字段,該_id 值在集合中必須是惟一的,以免重複鍵錯誤。
在 MongoDB 中,插入操做針對單個集合。 MongoDB 中的全部寫操做都是在單個文檔的級別上進行的
help: 顯示幫助。 db.help() 顯示數據庫方法的幫助。 db.<collection>.help() 顯示收集方法的幫助, <collection>能夠是現有的集合或不存在的集合的名稱。 show dbs 打印服務器上全部數據庫的列表。 use <db> 將當前數據庫切換到<db>。該 mongoshell 變量 db 被設置爲當前數據庫。 show collections 打印當前數據庫的全部集合的列表。 show users 打印當前數據庫的用戶列表。 show roles 打印用於當前數據庫的用戶定義和內置的全部角色的列表。 show profile 打印須要 1 毫秒或更多的五個最近的操做。有關詳細信息,請參閱數據庫分析器上的文檔。 show databases 打印全部可用數據庫的列表。
官方文檔: https://docs.mongodb.com/v3.4/tutorial/insert-documents/
MongoDB提供了將文檔插入到集合中的如下方法: db.collection.insertOne()
將單個文檔插入到集合中。 db.collection.insertMany()
將多個 文檔插入到集合中。 db.collection.insert()
將單個文檔或多個文檔插入到集合中。 db.collection.save()
根據文檔參數更新現有文檔或插入新文檔
命令集合:
db.test.insert( {"name":"keme","age":18,"ad":"北京市朝陽區"} ) db.test.insert( {"name":"xiaoke","age":17,"ad":"北京市朝陽區"} ) db.test.insert( {"name":"aaa","age":20,"ad":"北京市朝陽區"} ) db.test.insert( {"name":"xiaoxi","age":21,"ad":"北京市朝陽區"} ) db.test.insert( {"name":"xiaojian","age":28,"ad":"北京市朝陽區","sex":"boy"} )
執行結果
登陸mongo [root@mongo-160 ~]# mongo localhost:27017 >db.test.insert( {"name":"keme","age":18,"ad":"北京市朝陽區"} ) >db.test.insert( {"name":"xiaoke","age":17,"ad":"北京市朝陽區"} ) >db.test.insert( {"name":"aaa","age":20,"ad":"北京市朝陽區"} ) >db.test.insert( {"name":"xiaoxi","age":21,"ad":"北京市朝陽區"} ) >db.test.insert( {"name":"xiaojian","age":28,"ad":"北京市朝陽區","sex":"boy"} ) #查看插入結果 > db.test.find() { "_id" : ObjectId("5cfdbd4bceada13ff76c3afa"), "name" : "keme", "age" : 18, "ad" : "北京市朝陽區" } { "_id" : ObjectId("5cfdbd4bceada13ff76c3afb"), "name" : "xiaoke", "age" : 17, "ad" : "北京市朝陽區" } { "_id" : ObjectId("5cfdbd4bceada13ff76c3afc"), "name" : "aaa", "age" : 20, "ad" : "北京市朝陽區" } { "_id" : ObjectId("5cfdbd4bceada13ff76c3afd"), "name" : "xiaoxi", "age" : 21, "ad" : "北京市朝陽區" } { "_id" : ObjectId("5cfdbd4eceada13ff76c3afe"), "name" : "xiaojian", "age" : 28, "ad" : "北京市朝陽區", "sex" : "boy" }
官方文檔例子
#命令 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" } ]);
執行結果
> 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" } ... ]); { "acknowledged" : true, "insertedIds" : [ ObjectId("5cfdc5eaceada13ff76c3b02"), ObjectId("5cfdc5eaceada13ff76c3b03"), ObjectId("5cfdc5eaceada13ff76c3b04"), ObjectId("5cfdc5eaceada13ff76c3b05"), ObjectId("5cfdc5eaceada13ff76c3b06") ] }
db.collection.find(query , projection )
選擇集合或視圖中的文檔,並將光標返回 到所選文檔參數query類型是文件,可選的。用查詢運算符指定選擇過濾器要返回集合中的全部文檔請忽略此參數或傳遞一個空的文檔參數projection類型是文件,可選的。指定在與查詢過濾器匹配的文檔中返回的字段。要返回匹配文檔中的全部字段, 返回: 一個光標匹配的文件query 標準。當find()方法「返回文檔」時
,該方法實際上將光標返回到文檔。 $or
或者關係, $in
匹配多個件鍵
雖然可使用$or
運算符來表達下面查詢,但在同一字段上執行相等檢查時,請使用$in
運算符而不是$or運算符。
查詢全部
db.<collection>.find()
查詢單條
db.<collection>.findOne() > db.test.findOne() { "_id" : ObjectId("5cfdbd4bceada13ff76c3afa"), "name" : "keme", "age" : 18, "ad" : "北京市朝陽區" }
不少都是看官方文檔
> myCursor = db.inventory.find( { status: "D" } ) { "_id" : ObjectId("5cfdc5eaceada13ff76c3b04"), "item" : "paper", "qty" : 100, "size" : { "h" : 8.5, "w" : 11, "uom" : "in" }, "status" : "D" } { "_id" : ObjectId("5cfdc5eaceada13ff76c3b05"), "item" : "planner", "qty" : 75, "size" : { "h" : 22.85, "w" : 30, "uom" : "cm" }, "status" : "D" } # 至關於SQL語句的 select * from inventory where status="D";
示例2
# 這是找出json 裏面的值 > myCursor = db.inventory.find( { "size.uom": "in" } ) { "_id" : ObjectId("5cfdc5eaceada13ff76c3b03"), "item" : "notebook", "qty" : 50, "size" : { "h" : 8.5, "w" : 11, "uom" : "in" }, "status" : "A" } { "_id" : ObjectId("5cfdc5eaceada13ff76c3b04"), "item" : "paper", "qty" : 100, "size" : { "h" : 8.5, "w" : 11, "uom" : "in" }, "status" : "D" }
示例3:and
> myCursor = db.inventory.find( { status: "A", qty: { $lt: 30 } } ) { "_id" : ObjectId("5cfdc5eaceada13ff76c3b02"), "item" : "journal", "qty" : 25, "size" : { "h" : 14, "w" : 21, "uom" : "cm" }, "status" : "A" } 至關於sql 語句 select * from inventory where status="A" and qty< 30;
示例4:or
> myCursor = db.inventory.find( { $or: [ { status: "A" }, { qty: { $lt: 30 } } ] } ) { "_id" : ObjectId("5cfdc5eaceada13ff76c3b02"), "item" : "journal", "qty" : 25, "size" : { "h" : 14, "w" : 21, "uom" : "cm" }, "status" : "A" } { "_id" : ObjectId("5cfdc5eaceada13ff76c3b03"), "item" : "notebook", "qty" : 50, "size" : { "h" : 8.5, "w" : 11, "uom" : "in" }, "status" : "A" } { "_id" : ObjectId("5cfdc5eaceada13ff76c3b06"), "item" : "postcard", "qty" : 45, "size" : { "h" : 10, "w" : 15.25, "uom" : "cm" }, "status" : "A" } 至關於sql 語句: select * from inventory where status=A or qty<30;
示例5:正則
myCursor = db.inventory.find( {status: "A",$or: [ { qty: { $lt: 30 } }, { item: /^p/ } ]} ) 或者: myCursor = db.inventory.find( { status: "A", $or: [ { qty: { $lt: 30 } }, { item: /^p/ } ] } )
執行結果
> myCursor = db.inventory.find( { ... status: "A", ... $or: [ { qty: { $lt: 30 } }, { item: /^p/ } ] ... } ) { "_id" : ObjectId("5cfdc5eaceada13ff76c3b02"), "item" : "journal", "qty" : 25, "size" : { "h" : 14, "w" : 21, "uom" : "cm" }, "status" : "A" } { "_id" : ObjectId("5cfdc5eaceada13ff76c3b06"), "item" : "postcard", "qty" : 45, "size" : { "h" : 10, "w" : 15.25, "uom" : "cm" }, "status" : "A" } # 至關於sql語句 SELECT * FROM inventory WHERE status = "A" AND ( qty < 30 OR item LIKE "p%")
$eq 匹配等於指定值的值。
$gt 匹配大於指定值的值。
$gte 匹配大於或等於指定值的值。
$in 匹配數組中指定的任何值。
$lt 匹配小於指定值的值。
$lte 匹配小於或等於指定值的值。
$ne 匹配不等於指定值的全部值。
$nin不匹配數組中指定的值。
$and 使用邏輯鏈接查詢子句AND返回與兩個子句的條件相匹配的全部文檔。
$not 反轉查詢表達式的效果,並返回與查詢表達式不匹配的文檔。
$nor 使用邏輯鏈接查詢子句NOR返回全部沒法匹配兩個子句的文檔。
$or 使用邏輯鏈接查詢子句OR返回與任一子句的條件相匹配的全部文檔
MongoDB提供如下方法來更新集合中的文檔:
db.collection.updateOne(<filter>, <update>, <options>)即便可能有多個文檔經過過濾條件匹配到,可是也最多也只更新一個文檔 db.collection.updateMany(<filter>, <update>, <options>) 更新全部經過過濾條件匹配到的文檔 db.collection.replaceOne(<filter>, <replacement>, <options>) 即便可能有多個文檔經過過濾條件匹配到,可是也最多也只替換一個文檔 db.collection.update()即便可能有多個文檔經過過濾條件匹配到,可是也最多也只更新或者替換一個文檔。
示例1:更新單條數據
db.inventory.updateOne( { "item" : "paper" }, // specifies the document to update { $set: { "size.uom" : "cm", "status" : "P" }, $currentDate: { "lastModified": true } } )
執行結果
> db.inventory.updateOne( ... { "item" : "paper" }, // specifies the document to update ... { ... $set: { "size.uom" : "cm", "status" : "P" }, ... $currentDate: { "lastModified": true } ... } ... ) { "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 } # 查看更新是否成功 > myCursor = db.inventory.find( { "item": "paper" } ) { "_id" : ObjectId("5cfdc5eaceada13ff76c3b04"), "item" : "paper", "qty" : 100, "size" : { "h" : 8.5, "w" : 11, "uom" : "cm" }, "status" : "P", "lastModified" : ISODate("2019-06-10T03:32:31.190Z") } 更新成功了
示例2:更新多條數據
db.inventory.updateMany( { "qty" : { $lt: 50 } }, // specifies the documents to update { $set: { "size.uom" : "cm", "status": "P" }, $currentDate : { "lastModified": true } } )
執行結果
> db.inventory.updateMany( ... { "qty" : { $lt: 50 } }, // specifies the documents to update ... { ... $set: { "size.uom" : "cm", "status": "P" }, ... $currentDate : { "lastModified": true } ... } ... ) { "acknowledged" : true, "matchedCount" : 2, "modifiedCount" : 2 } #查看修改的數據 > myCursor = db.inventory.find( { "qty": { $lt: 50 } } ) { "_id" : ObjectId("5cfdc5eaceada13ff76c3b02"), "item" : "journal", "qty" : 25, "size" : { "h" : 14, "w" : 21, "uom" : "cm" }, "status" : "P", "lastModified" : ISODate("2019-06-10T03:35:53.575Z") } { "_id" : ObjectId("5cfdc5eaceada13ff76c3b06"), "item" : "postcard", "qty" : 45, "size" : { "h" : 10, "w" : 15.25, "uom" : "cm" }, "status" : "P", "lastModified" : ISODate("2019-06-10T03:35:53.575Z") }
MongoDB提供如下方法來刪除集合的文檔:
db.collection.remove() 刪除單個文檔或與指定過濾器匹配的全部文檔。 參數{},清空集合 db.collection.drop()此方法獲取受影響的數據庫上的寫入鎖定,並將阻止其餘操做,直到 其完成。 不加參數刪除全部數據包括索引 db.collection.deleteOne() 最多刪除與指定過濾器匹配的單個文檔,即便多個文檔可能與指定的過濾器匹配。 db.collection.deleteMany() 刪除與指定過濾器匹配的全部文檔。
示例
> show dbs admin 0.000GB local 0.000GB test 0.000GB > use test switched to db test > show collections inventory test # 刪除單條數據 db.inventory.deleteOne( { "status": "D" } // specifies the document to delete ) # 刪除多條數據 db.inventory.deleteMany( { "status" : "P" } // specifies the documents to delete )
默認狀況下,建立索引將阻止數據庫上的全部其餘操做
。在集合上構建索引時,保存集合的數據庫對於讀取或寫入操做是不可用的,直到索引構建完成。任何須要對全部數據庫(例如listDatabases)進行讀或寫鎖定的操做將等待前臺索引構建完成。
對於可能須要長時間運行的索引建立操做,能夠考慮 background 選項,這樣MongoDB數據庫在索引建立期間仍然是可用的。例如,在 people 集合的 zipcode 鍵上建立一個索引,這個過程在後臺運行,可使用以下方式:
db.people.createIndex( { zipcode: 1}, {background: true} )
默認 MongoDB 索引建立的 background 是 false
索引優化: db.test.find({「id」:100}).explain()
單鍵索引(Single Field Indexes):
在一個鍵上建立的索引就是單鍵索引,單鍵索引是最多見的索引,如MongoDB默認建立的_id的索引就是單鍵索引。
複合索引(Compound Indexes):
在多個鍵上創建的索引就是複合索引。
多鍵索引(Multikey Index):
若是在一個數組上面建立索引, MongoDB會本身決定,是否要把這個索引建成多鍵索引。
地理空間索引(Geospatial Indexes and Queries):
MongoDB支持幾種類型的地理空間索引。其中最經常使用的是 2dsphere 索引(用於地球表面類型的地圖)和 2d 索引(用於平面地圖和時間連續的數據)經度和緯度。
2d:
2d 索引用於扁平化表面,而不是球體表面,不然極點附近會出現大量的扭曲變形。
全文索引(Text Indexes):
當文本塊比較大的時候,正則表達式搜索會很是慢,並且沒法處理語言理解的問題(如entry 和 entries 應該算是匹配的)。使用全文索引能夠很是快地進行文本搜索,就如同內置了多種語言分詞機制的支持同樣。建立索引的開銷都比較大,全文索引的開銷更大。建立索引時,需後臺或離線建立。
哈希索引(Hashed Index):
哈希索引能夠支持相等查詢,可是哈希索引不支持範圍查詢。您可能沒法建立一個帶有哈希索引鍵的複合索引或者對哈希索引施加惟一性的限制。可是,您能夠在同一個鍵上同時建立一個哈希索引和一個遞增/遞減(例如,非哈希)的索引,這樣MongoDB對於範圍查詢就會自
動使用非哈希的索引。
示例:建立一個索引
# 查看默認集合文檔信息,也就是沒有索引 > db.test.find() { "_id" : ObjectId("5cfdbd4bceada13ff76c3afa"), "name" : "keme", "age" : 18, "ad" : "北京市朝陽區" } { "_id" : ObjectId("5cfdbd4bceada13ff76c3afb"), "name" : "xiaoke", "age" : 17, "ad" : "北京市朝陽區" } { "_id" : ObjectId("5cfdbd4bceada13ff76c3afc"), "name" : "aaa", "age" : 20, "ad" : "北京市朝陽區" } { "_id" : ObjectId("5cfdbd4bceada13ff76c3afd"), "name" : "xiaoxi", "age" : 21, "ad" : "北京市朝陽區" } { "_id" : ObjectId("5cfdbd4eceada13ff76c3afe"), "name" : "xiaojian", "age" : 28, "ad" : "北京市朝陽區", "sex" : "boy" } > db.test.find({"age":{ $lt: 20 }}).explain() { "queryPlanner" : { "plannerVersion" : 1, "namespace" : "test.test", "indexFilterSet" : false, "parsedQuery" : { "age" : { "$lt" : 20 } }, "winningPlan" : { "stage" : "COLLSCAN", "filter" : { "age" : { "$lt" : 20 } }, "direction" : "forward" }, "rejectedPlans" : [ ] }, "serverInfo" : { "host" : "mongo-160", "port" : 27017, "version" : "3.4.20", "gitVersion" : "447847d93d6e0a21b018d5df45528e815c7c13d8" }, "ok" : 1 }
建立一個索引
> db.test.createIndex( {age:1} ) { "createdCollectionAutomatically" : false, "numIndexesBefore" : 1, "numIndexesAfter" : 2, "ok" : 1 } # 獲得集合的全部索引 > db.test.getIndexes() [ { "v" : 2, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "test.test" }, { "v" : 2, "key" : { "age" : 1 }, "name" : "age_1", "ns" : "test.test" } ]
再次查看執行計劃
> db.test.find({"age":{ $lt: 20 }}).explain()
刪除索引
> db.test.dropIndex( {age:1} ) { "nIndexesWas" : 2, "ok" : 1 }
官方文檔:
https://docs.mongodb.com/v3.4/reference/program/
mongo 是MongoDB的交互式JavaScript shell接口,爲系統管理員提供強大的界面,也爲開發
人員直接用數據庫測試查詢和操做的方式。 mongo還提供了一個功能齊全的JavaScript環境,與MongoDB一塊兒使用。本文檔介紹了mongoshell 的基本調用及其用法概述。
mongod 是 Mongodb 系統的主要守護進程,它處理數據請求,管理數據訪問,並執行後臺管理操做。啓動進程指定配置文件,控制數據庫的行爲
mongos 對於「MongoDB Shard」,是用於處理來自應用層的查詢的MongoDB分片配置的路由服務,並肯定此數據在分片集羣中的位置, 以完成這些操做。從應用程序的角度來看,一個 mongos實例與任何其餘MongoDB實例的行爲相同。
mongostat 實用程序能夠快速概覽當前正在運行的mongod 或mongos 實例的狀態。mongostat在功能上相似於UNIX / Linux文件系統實用程序vmstat,但提供有關的數據 mongod和mongos實例。
[root@mongo-160 ~]# mongostat -h 10.0.0.160:27017 #若是開啓用戶認證:須要添加-u -p --authenticationDatabase=
mongotop提供了一種跟蹤MongoDB實例讀取和寫入數據的時間量的方法。 mongotop 提供每一個收集級別的統計信息。默認狀況下, mongotop每秒返回一次值
[root@mongo-160 ~]# mongotop -h 10.0.0.160:27017 若是開啓用戶認證:須要添加 -u -p --authenticationDatabase=
本身的實驗機器沒什麼讀寫
mongooplog是一個簡單的工具,能夠從遠程服務器的複製 oplog輪詢操做,並將其應用於本地服務器。此功能支持某些類型的實時遷移,這些遷移要求源服務器保持聯機並在整個遷移過程當中運行。一般,此命令將採用如下形式:mongooplog - from mongodb0.example.net --host mongodb1.example.net
mongoperf是一種獨立於MongoDB檢查磁盤I / O性能的實用程序。它是隨機磁盤I / O的測試 ,並呈現結果。
例如: echo 「{nThreads: 16, fileSizeMB: 10000, r: true, w: true}」 | mongoperf 在這個操做中: mongoperf 測試直接物理隨機讀寫io的,使用16個併發閱讀器線程。 mongoperf 使用10 GB的測試文件。 或者參數寫入文件裏 mongoperf < config
mongoexport是一個實用程序,能夠導出存儲在MongoDB實例中的數據,生成一個JSON或
CSV
# 導出test庫下的test集合中 ,條件爲 age 大於等於17 而且小於等於20 ,導出文件爲test.json [root@mongo-160 ~]# mongoexport -h 10.0.0.160:27017 -d test -c test -o test.json -q '{"age" : {$gte:17,$lte:20}}' 2019-06-10T16:46:32.312+0800 connected to: 10.0.0.160:27017 2019-06-10T16:46:32.312+0800 exported 3 records # 查看導出的內容 [root@mongo-160 ~]# cat test.json {"_id":{"$oid":"5cfdbd4bceada13ff76c3afa"},"name":"keme","age":18.0,"ad":"北京市朝陽區"} {"_id":{"$oid":"5cfdbd4bceada13ff76c3afb"},"name":"xiaoke","age":17.0,"ad":"北京市朝陽區"} {"_id":{"$oid":"5cfdbd4bceada13ff76c3afc"},"name":"aaa","age":20.0,"ad":"北京市朝陽區"}
mongoimport工具從由其餘第三方導出工具建立或可能的擴展JSON, CSV或TSV導出導入內容
#導入到test庫下的test集合,導入以前刪除原來的集合 [root@mongo-160 ~]# mongoimport -d test -c test --type json --drop < test.json 2019-06-10T16:53:11.092+0800 connected to: localhost 2019-06-10T16:53:11.093+0800 dropping: test.test 2019-06-10T16:53:11.101+0800 imported 3 documents
避免使用mongoimport和mongoexport徹底實例生產備份。它們不可靠地保存全部豐富的 BSON數據類型,由於JSON只能表示BSON支持的類型的一個子集,使用該 –type=csv選項爲輸出指定CSV格式
bsondump 轉換BSON文件轉換爲咱們可直接讀的格式,包括JSON。例如,
bsondump對於讀取mongodump輸出文件頗有用。bsondump 是用於檢查BSON文件的診斷工具,而不是用於數據攝取或其餘應用程序使用的工具
找個備份文件
# 我這沒有bson 文件,先標註用法 shell> bsondump xxxx.bson > xxxx.json
mongofiles 實用程序能夠從命令行操做在GridFS對象中存儲在MongoDB實例中的文件。它特別有用,由於它提供了存儲在文件系統和GridFS之間的對象之間的接口。
官方文檔:
https://docs.mongodb.com/v3.4/tutorial/enable-authentication/
認證是驗證客戶端身份的過程。當啓用訪問控制(即受權)時,MongoDB要求全部客戶端進
行身份驗證,以肯定其訪問。認證方法:爲了驗證用戶,MongoDB提供了該 db.auth()方法。
對於mongoshell和MongoDB工具,能夠經過從命令行傳入用戶身份驗證信息來驗證用戶,認證機制
MongoDB支持多種認證機制:
SCRAM-SHA-1
3.0版中更改: 3.0中建立的新挑戰響應用戶將使用 SCRAM-SHA-1。若是使用2.6用戶數據,MongoDB 3.0將繼續使用MONGODB-CR。
x.509證書認證。
除了支持上述機制外,MongoDB Enterprise還支持如下機制:
除了驗證客戶端的身份以外,MongoDB還能夠要求副本集和分片集羣的成員對其各自的副本
集或分片集羣進行身份驗證。有關 詳細信息,請參閱分片集上的認證
在分片集羣中,客戶端一般直接對mongos實例進行身份驗證 。可是,某些維護操做可能需
要直接對特定的分片進行身份驗證。
用戶管理界面
要添加用戶, MongoDB 提供了該 db.createUser()方法。添加用戶時,您能夠爲用戶分配色以授予權限。
注意:
在數據庫中建立的第一個用戶應該是具備管理其餘用戶的權限的用戶管理員。
你還能夠更新現有用戶,例如更改密碼並授予或撤銷角色
認證數據庫
添加用戶時,能夠在特定數據庫中建立用戶。該數據庫是用戶的身份驗證數據庫。
用戶能夠跨不一樣數據庫擁有權限; 即用戶的權限不限於認證數據庫。經過分配給其餘數據庫中的用戶角色,在一個數據庫中建立的用戶能夠具備對其餘數據庫的操做權限。
用戶名和認證數據庫做爲該用戶的惟一標識符。也就是說,若是兩個用戶具備相同的名稱,
可是在不一樣的數據庫中建立,則它們是兩個不一樣的用戶。若是您打算擁有具備多個數據庫權
限的單個用戶,請在適用的數據庫中建立具備角色的單個用戶,而不是在不一樣數據庫中屢次
建立用戶。
一些相關方法
db.auth() 將用戶驗證到數據庫。 db.changeUserPassword() 更改現有用戶的密碼。 db.createUser() 建立一個新用戶。 db.dropUser() 刪除單個用戶。 db.dropAllUsers() 刪除與數據庫關聯的全部用戶。 db.getUser() 返回有關指定用戶的信息。 db.getUsers() 返回有關與數據庫關聯的全部用戶的信息。 db.grantRolesToUser() 授予用戶角色及其特權。 db.removeUser() 已過期。從數據庫中刪除用戶。 db.revokeRolesFromUser() 從用戶中刪除角色。 db.updateUser() 更新用戶數據。 db.createRole() 建立角色並指定其特權。 db.dropRole() 刪除用戶定義的角色。 db.dropAllRoles() 刪除與數據庫關聯的全部用戶定義的角色。 db.getRole() 返回指定角色的信息。 db.getRoles() 返回數據庫中全部用戶定義角色的信息。 db.grantPrivilegesToRole() 將權限分配給用戶定義的角色。 db.revokePrivilegesFromRole() 從用戶定義的角色中刪除指定的權限 db.grantRolesToRole() 指定用戶定義的角色從中繼承權限的角色。 db.revokeRolesFromRole() 從角色中刪除繼承的角色。 db.updateRole() 更新用戶定義的角色
dbAdmin, dbOwner, userAdminAnyDatabase
提供在當前數據庫上建立和修改角色和用戶的功能。該角色還間接地提供 對數據庫的超級用戶訪問,或者若是做用於admin數據庫的集羣。該userAdmin角色容許用戶授予任何用戶任何特權,包括本身。
該admin數據庫包括用於管理整個系統,而不只僅是一個單一的數據庫如下角色。這些角色包括但不限於複製集和分片集羣管理功能。
clusterAdmin :提供最大的集羣管理訪問。這個角色組合由授予的權限clusterManager, clusterMonitor和hostManager角色。另外,角色提供了dropDatabase動做。
clusterManager : 在集羣上提供管理和監控動做。具備該角色的用戶能夠訪問config和local數據庫,其在分片和複製所使用的
# 建立角色 db.createRole( { role: 「test」, privileges: [ { resource: { db: 「test」, collection: 「」 }, actions: [ 「insert」,「update」,remove] }, ], roles: [ { role: 「read」, db: 「test」 } ] }, { w: 「majority」 , wtimeout: 5000 }) # 建立用戶,添加到相應角色 db.createUser({user:"ke",pwd:"123456",roles:[ { role:"test", db:"test" }]}) #上面自定義角色這個模擬的語法示例,沒在實驗環境作演示
[root@mongo-160 ~]# mongo localhost:27017 #查看當前mongo實例有哪些用戶 > db.getUsers() [ ] 空的,沒有用戶 # 建立用戶 > db.createUser({user: "admin",pwd: "123456",roles:[ { role: "root", db:"admin"}]}) Successfully added user: { "user" : "admin", "roles" : [ { "role" : "root", "db" : "admin" } ] } # 查看用戶 > db.getUsers() [ { "_id" : "test.admin", "user" : "admin", "db" : "test", "roles" : [ { "role" : "root", "db" : "admin" } ] } ]
末尾添加以下兩行內容 [root@mongo-160 ~]# vim /opt/mongodb/conf/mongodb.conf security: #認證 authorization: enabled #啓用或者禁用基於角色的訪問控制來管理每一個用戶對數據庫資源和操做的訪問enabled 或者 disables #重啓生效 [root@mongo-160 ~]# mongod -f /opt/mongodb/conf/mongodb.conf --shutdown killing process with pid: 79647 [root@mongo-160 ~]# mongod -f /opt/mongodb/conf/mongodb.conf about to fork child process, waiting until server is ready for connections. forked process: 93037 child process started successfully, parent exiting
配置問權限認證後須要重啓節點,再次登錄若是不使用帳號密碼就查看不了數據
[root@mongo-160 ~]# mongo localhost:27017 -u admin -p123456 > show dbs admin 0.000GB local 0.000GB test 0.000GB
設置不一樣帳號權限
# 用admin用戶 建立一個schools 庫, 建立一個students集合,插入一條數據 > use school switched to db school > show collections > db.students.insert ( {"name":"keme"} ) WriteResult({ "nInserted" : 1 }) # 查看集合 > show collections students
而後建立不一樣帳號權限
use test # 建立一個用戶keme,在test 數據庫下有讀寫, 在school 下只有讀取 db.createUser( { user: "keme", pwd: "123456", roles: [ { role: "readWrite", db: "test" }, { role: "read", db: "school" } ] } )
執行結果
> use test switched to db test > db.createUser( ... { ... user: "keme", ... pwd: "123456", ... roles: [ { role: "readWrite", db: "test" }, ... { role: "read", db: "school" } ] ... } ... ) Successfully added user: { "user" : "keme", "roles" : [ { "role" : "readWrite", "db" : "test" }, { "role" : "read", "db" : "school" } ] }
登錄keme用戶查看
> use test switched to db test > db.auth("keme","123456") 1 > show collections inventory test # 驗證讀 > db.test.findOne() { "_id" : ObjectId("5cfdbd4bceada13ff76c3afa"), "name" : "keme", "age" : 18, "ad" : "北京市朝陽區" } # 驗證寫 > db.test.insertOne( {"name":"xiaojian","age":20,"ad":"北京市朝陽區"} ) { "acknowledged" : true, "insertedId" : ObjectId("5cff09d8ad4a9f4bf7ffb242") } # 切換到 school 庫,發現可讀不可寫 > use school switched to db school #讀取 > db.students.findOne() { "_id" : ObjectId("5cff0753ad4a9f4bf7ffb241"), "name" : "keme" } #寫入,報錯 > db.students.insert( {"name":"xiaoke"} ) WriteResult({ "writeError" : { "code" : 13, "errmsg" : "not authorized on school to execute command { insert: \"students\", documents: [ { _id: ObjectId('5cff0a46ad4a9f4bf7ffb243'), name: \"xiaoke\" } ], ordered: true }" } })
簡單的導入導出能夠用mongoexport 和 mongoimport
mongodump的參數與mongoexport的參數基本一致
經常使用參數
參數 參數說明 -h 指明數據庫宿主機的IP -u 指明數據庫的用戶名 -p 指明數據庫的密碼 -d 指明數據庫的名字 -c 指明collection的名字 -o 指明到要導出的文件名 -q 指明導出數據的過濾條件 --authenticationDatabase 驗證數據的名稱 --gzip 備份時壓縮
舉例:
# 建立一個備份目錄點 [root@mongo-160 ~]# mkdir -p /data/backup/mongo/ [root@mongo-160 ~]# mongo 10.0.0.160:27017 -u admin -p 123456 >use admin #建立相應的管理用戶 >db.createUser( { user: "kemeadmin", pwd: "123456", roles: [ { role: "root", db: "admin" } ] } ) > exit bye #進行全備 [root@mongo-160 ~]# mongodump -h 10.0.0.160:27017 -u kemeadmin -p123456 --authenticationDatabase admin -o /data/backup/mongo/full20190611 #查看是否備份成功 [root@mongo-160 ~]# cd /data/backup/mongo/full20190611/ [root@mongo-160 full20190611]# ls admin school test [root@mongo-160 full20190611]# cd test/ [root@mongo-160 test]# ls inventory.bson inventory.metadata.json test.bson test.metadata.json [root@mongo-160 test]# pwd /data/backup/mongo/full20190611/test
備份某個庫
# 備份test 庫 mongodump -h 10.0.0.160:27017 -u kemeadmin -p123456 --authenticationDatabase admin -d test -o /data/backup/mongo [root@mongo-160 ~]# cd /data/backup/mongo/ [root@mongo-160 mongo]# ls full20190611 test [root@mongo-160 mongo]# cd test/ [root@mongo-160 test]# ls inventory.bson inventory.metadata.json test.bson test.metadata.json # 備份test庫下的inventory 集合 [root@mongo-160 ~]# mongodump -h 10.0.0.160:27017 -ukemeadmin -p123456 --authenticationDatabase admin -d test -c inventory -o /data/backup/mongo/
壓縮備份
#壓縮備份單個庫 [root@mongo-160 ~]# mongodump -h 10.0.0.160:27017 -ukemeadmin -p123456 --authenticationDatabase admin -d school -o /data/backup/mongo/ --gzip # 壓縮備份某個集合也是同樣的加上--gzip
mongorestore與mongoimport參數相似
經常使用參數以下:
參數 參數說明 -h 指明數據庫宿主機的IP -u 指明數據庫的用戶名 -p 指明數據庫的密碼 -d 指明數據庫的名字 -c 指明collection的名字 -o 指明到要導出的文件名 -q 指明導出數據的過濾條件 --authenticationDatabase 驗證數據的名稱 --gzip 備份時壓縮 --drop 恢復的時候把以前的集合drop掉
全庫備份中恢復單庫(基於以前的全庫備份)
# 從全庫中恢復test庫 [root@mongo-160 ~]# mongorestore -h 10.0.0.160:27017 -ukemeadmin -p123456 --authenticationDatabase admin -d test --drop /data/backup/mongo/full20190611/test
恢復某個庫,不刪除以前的集合看看數據有什麼變化
作以前刪除一條數據,好驗證 > use test switched to db test > db.test.find() { "_id" : ObjectId("5cfdbd4bceada13ff76c3afa"), "name" : "keme", "age" : 18, "ad" : "北京市朝陽區" } { "_id" : ObjectId("5cfdbd4bceada13ff76c3afb"), "name" : "xiaoke", "age" : 17, "ad" : "北京市朝陽區" } { "_id" : ObjectId("5cfdbd4bceada13ff76c3afc"), "name" : "aaa", "age" : 20, "ad" : "北京市朝陽區" } { "_id" : ObjectId("5cff09d8ad4a9f4bf7ffb242"), "name" : "xiaojian", "age" : 20, "ad" : "北京市朝陽區" } # 刪除名字是aaa的數據 > db.test.deleteOne( {"name":"aaa"} ) { "acknowledged" : true, "deletedCount" : 1 } > db.test.find() { "_id" : ObjectId("5cfdbd4bceada13ff76c3afa"), "name" : "keme", "age" : 18, "ad" : "北京市朝陽區" } { "_id" : ObjectId("5cfdbd4bceada13ff76c3afb"), "name" : "xiaoke", "age" : 17, "ad" : "北京市朝陽區" } { "_id" : ObjectId("5cff09d8ad4a9f4bf7ffb242"), "name" : "xiaojian", "age" : 20, "ad" : "北京市朝陽區" } 恢復test庫,看看有沒有aaa這個數據 [root@mongo-160 ~]# mongorestore -h 10.0.0.160:27017 -ukemeadmin -p123456 --authenticationDatabase admin -d test /data/backup/mongo/full20190611/test/ #登陸查看 [root@mongo-160 ~]# mongo localhost:27017 -uadmin -p123456 > use test switched to db test > db.test.find() { "_id" : ObjectId("5cfdbd4bceada13ff76c3afa"), "name" : "keme", "age" : 18, "ad" : "北京市朝陽區" } { "_id" : ObjectId("5cfdbd4bceada13ff76c3afb"), "name" : "xiaoke", "age" : 17, "ad" : "北京市朝陽區" } { "_id" : ObjectId("5cff09d8ad4a9f4bf7ffb242"), "name" : "xiaojian", "age" : 20, "ad" : "北京市朝陽區" } { "_id" : ObjectId("5cfdbd4bceada13ff76c3afc"), "name" : "aaa", "age" : 20, "ad" : "北京市朝陽區" } ok ,恢復成功
mongoexport/mongoimport與mongodump/mongorestore的對比
mongoexport/mongoimport導入/導出的是JSON格式,而mongodump/mongorestore導入/導出的是BSON格式。
JSON可讀性強但體積較大,BSON則是二進制文件,體積小但對人幾乎沒有可讀性。
在一些mongodb版本之間,BSON格式可能會隨版本不一樣而有所不一樣,因此不一樣版本之間用mongodump/mongorestore可能不會成功,具體要看版本之間的兼容性。當沒法使用BSON進行跨版本的數據遷移的時候,使用JSON格式即mongoexport/mongoimport是一個可選項。跨版本的mongodump/mongorestore並不推薦,實在要作請先檢查文檔看兩個版本是否兼容(大部分時候是的)。
JSON雖然具備較好的跨版本通用性,但其只保留了數據部分,不保留索引,帳戶等其餘基礎信息。使用時應該注意。
備份不是想我那樣寫的那麼簡單,我上面只寫了一些工具的用法,一些平常的維護。從長遠考慮,還須要考慮更多
能夠看看阿里雲的雲mongodb 一些備份恢復文檔
https://help.aliyun.com/document_detail/55008.html?spm=a2c4g.11186623.6.677.4039d6afePr5YU
監控及時得到應用的運行狀態信息,在問題出現時及時發現。
監控哪些
CPU、內存、磁盤I/O、應用程序(MongoDB)、進程監控(ps -aux)、錯誤日誌監控
一些內部狀態能夠查看:
db.serverStatus() 查看實例運行狀態(內存使用、鎖、用戶鏈接等信息) 經過比對先後快照進行性能分析 "connections" # 當前鏈接到本機處於活動狀態的鏈接數 "activeClients" # 鏈接到當前實例處於活動狀態的客戶端數量 "locks" # 鎖相關參數 "opcounters" # 啓動以後的參數 "opcountersRepl" # 複製想關 "storageEngine" # 查看數據庫的存儲引擎 "mem" # 內存相關 db.stats() 顯示信息說明: "db" : "test" ,表示當前是針對"test"這個數據庫的描述。想要查看其餘數據庫,能夠先運行$ use databasename(e.g $use admiin). "collections" : 3,表示當前數據庫有多少個collections.能夠經過運行show collections查看當前數據庫具體有哪些collection. "objects" : 5,表示當前數據庫全部collection總共有多少行數據。顯示的數據是一個估計值,並非很是精確。 "avgObjSize" : 36,表示每行數據是大小,也是估計值,單位是bytes "dataSize" : 468,表示當前數據庫全部數據的總大小,不是指佔有磁盤大小。單位是bytes "storageSize" : 13312,表示當前數據庫佔有磁盤大小,單位是bytes,由於mongodb有預分配空間機制,爲了防止當有大量數據插入時對磁盤的壓力,所以會事先多分配磁盤空間。 "numExtents" : 3,彷佛沒有什麼真實意義。我弄明白以後再詳細補充說明。 "indexes" : 1 ,表示system.indexes表數據行數。 "indexSize" : 8192,表示索引佔有磁盤大小。單位是bytes "fileSize" : 201326592,表示當前數據庫預分配的文件大小,例如test.0,test.1,不包括test.ns。
mongostat在功能上相似於UNIX / Linux文件系統實用程序vmstat
參數 參數說明 insert 每秒插入量 query 每秒查詢量 update 每秒更新量 delete 每秒刪除量 conn 當前鏈接數 qr|qw 客戶端查詢排隊長度(讀|寫)最好爲0,若是有堆積,數據庫處理慢。 ar|aw 活躍客戶端數量(讀|寫) time 當前時間
mongotop提供了一種跟蹤MongoDB實例讀取和寫入數據的時間量的方法。
[root@mongo-160 ~]# mongotop -h 10.0.0.160:27017 -ukemeadmin -p123456 --authenticationDatabase admin
參數說明:
ns:數據庫命名空間,後者結合了數據庫名稱和集合。
total:mongod在這個命令空間上花費的總時間。
read:在這個命令空間上mongod執行讀操做花費的時間。
write:在這個命名空間上mongod進行寫操做花費的時間。
db.currentOp() 查看數據庫當前執行什麼操做。 用於查看長時間運行進程。 經過(執行時長、操做、鎖、等待鎖時長)等條件過濾。 若是發現一個操做太長,把數據庫卡死的話,能夠用這個命令殺死他:> db.killOp() db.serverStatus() db.stats()
禁止內存大頁和root 用戶操做
源碼包安裝(二進制)
備份、可能的話不一樣機房備份
開啓認證、自定義角色、權限最小化、防火牆限制IP
索引後臺建立,去掉程序用戶建立索引權限
後臺操做最好在業務低峯期
數據庫監控
其實上面我全是用root 用戶登陸操做的,這只是爲了我本身環境操做方便。應該有專門的程序用戶來操做和管理mongodb應用。