mogodb應用

NoSQL介紹

NoSQL簡介

NoSQL(NoSQL = Not Only SQL ),意即”不僅僅是SQL”。
在現代的計算系統上每天網絡上都會產生龐大的數據量。
這些數據有很大一部分是由關係數據庫管理系統(RDMBSs)來處理。 1970 年 E.F.Codd’s 提出的
關係模型的論文 “A relational model of data for large shared data banks”,這使得數據建模和應用程
序編程更加簡單。
通過應用實踐證明,關係模型是非常適合於客戶服務器編程,遠遠超出預期的利益,今天它是結構
化數據存儲在網絡和商務應用的主導技術。
NoSQL 是一項全新的數據庫革命性運動,早期就有人提出,發展至2009 年趨勢越發高漲。NoSQL
的擁護者們提倡運用非關係型的數據存儲,相對於鋪天蓋地的關係型數據庫運用,這一概念無疑是
一種全新的思維的注入。

什麼是NoSQL

NoSQL,指的是非關係型的數據庫。NoSQL 有時也稱作Not Only SQL 的縮寫,是對不同於傳統的
關係型數據庫的數據庫管理系統的統稱。
對NoSQL 最普遍的解釋是”非關聯型的”,強調Key-Value Stores 和文檔數據庫的優點,而不是單
純的反對RDBMS。
NoSQL 用於超大規模數據的存儲。(例如谷歌或Facebook 每天爲他們的用戶收集萬億比特的數
據)。這些類型的數據存儲不需要固定的模式,無需多餘操作就可以橫向擴展。

爲什麼使用NoSQL

今天我們可以通過第三方平臺(如:Google,Facebook 等)可以很容易的訪問和抓取數據。用戶的個
人信息,社交網絡,地理位置,用戶生成的數據和用戶操作日誌已經成倍的增加。我們如果要對這
些用戶數據進行挖掘,那SQL 數據庫已經不適合這些應用了, NoSQL 數據庫的發展也卻能很好的處
理這些大的數據。

MongoDB簡介

Mongodb 由C++語言編寫的,是一個基於分佈式文件存儲的開源數據庫系統。,是專爲可擴展性,
高性能和高可用性而設計的數據庫, 是非關係型數據庫中功能最豐富,最像關係型數據庫的,它支
持的數據結構非常散,是類似 json 的 bjson 格式,因此可以存儲比較複雜的數據類型。
MongoDB 的(來自於英文單詞“了Humongous”,中文含義爲“龐大”)是可以應用於各種規模
的企業,各個行業以及各類應用程序的開源數據庫。作爲一個適用於敏捷開發的數據庫,MongoDB
的的數據模式可以隨着應用程序的發展而靈活地更新。
MongoDB 以一種叫做 BSON(二進制 JSON)的存儲形式將數據作爲文檔存儲。具有相似結構的
文檔通常被整理成集合。可以把這些集合看成類似於關係數據庫中的表: 文檔和行相似, 字段和
列相似。

MongoDB數據格式

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


MongoDB特點

高性能: Mongodb 提供高性能的數據持久性,尤其是支持嵌入式數據模型減少數據庫系統上的
I/O 操作,索引支持能快的查詢,並且可以包括來嵌入式文檔和數組中的鍵
豐富的語言查詢: Mongodb 支持豐富的查詢語言來支持讀寫操作(CRUD)以及數據彙總,文本
搜索和地理空間索引
高可用性: Mongodb 的複製工具,成爲副本集,提供自動故障轉移和數據冗餘,
水平可擴展性: Mongodb 提供了可擴展性,作爲其核心功能的一部分,分片是將數據分,在一組
計算機上。
支持多種存儲引擎: WiredTiger 存儲引擎和、 MMAPv1 存儲引擎和 InMemory 存儲引擎

MongoDB包含的程序

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。

應用場景

作者:阿里云云棲號
鏈接:https://www.zhihu.com/question/32071167/answer/147896283
來源:知乎
著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。

案例1用在應用服務器的日誌記錄,查找起來比文本靈活,導出也很方便。也是給應用練手,從外圍系統開始使用MongoDB。
用在一些第三方信息的獲取或者抓取,因爲MongoDB的schema-less,所有格式靈活,不用爲了各種格式不一樣的信息專門設計統一的格式,極大的減少開發的工作。案例2mongodb之前有用過,主要用來存儲一些監控數據,No schema 對開發人員來說,真的很方便,增加字段不用改表結構,而且學習成本極低。案例3使用MongoDB做了O2O快遞應用,·將送快遞騎手、快遞商家的信息(包含位置信息)存儲在 MongoDB,然後通過 MongoDB 的地理位置查詢,這樣很方便的實現了查找附近的商家、騎手等功能,使得快遞騎手能就近接單,目前在使用MongoDB 上沒遇到啥大的問題,官網的文檔比較詳細,很給力。經常跟一些同學討論 MongoDB 業務場景時,會聽到類似『你這個場景 mysql 也能解決,沒必要一定用 MongoDB』的聲音,的確,並沒有某個業務場景必須要使用 MongoDB才能解決,但使用 MongoDB 通常能讓你以更低的成本解決問題(包括學習、開發、運維等成本),下面是 MongoDB 的主要特性,大家可以對照自己的業務需求看看,匹配的越多,用 MongoDB 就越合適。MongoDB 特性優勢事務支持MongoDB 目前只支持單文檔事務,需要複雜事務支持的場景暫時不適合靈活的文檔模型JSON 格式存儲最接近真實對象模型,對開發者友好,方便快速開發迭代高可用複製集滿足數據高可靠、服務高可用的需求,運維簡單,故障自動切換可擴展分片集羣海量數據存儲,服務能力水平擴展高性能mmapv1、wiredtiger、mongorocks(rocksdb)、in-memory 等多引擎支持滿足各種場景需求強大的索引支持地理位置索引可用於構建 各種 O2O 應用、文本索引解決搜索的需求、TTL索引解決歷史數據自動過期的需求Gridfs解決文件存儲的需求aggregation & mapreduce解決數據分析場景需求,用戶可以自己寫查詢語句或腳本,將請求都分發到 MongoDB 上完成從目前阿里雲 MongoDB 雲數據庫上的用戶看,MongoDB 的應用已經滲透到各個領域,比如遊戲、物流、電商、內容管理、社交、物聯網、視頻直播等,以下是幾個實際的應用案例。遊戲場景,使用 MongoDB 存儲遊戲用戶信息,用戶的裝備、積分等直接以內嵌文檔的形式存儲,方便查詢、更新物流場景,使用 MongoDB 存儲訂單信息,訂單狀態在運送過程中會不斷更新,以 MongoDB 內嵌數組的形式來存儲,一次查詢就能將訂單所有的變更讀取出來。社交場景,使用 MongoDB 存儲存儲用戶信息,以及用戶發表的朋友圈信息,通過地理位置索引實現附近的人、地點等功能物聯網場景,使用 MongoDB 存儲所有接入的智能設備信息,以及設備彙報的日誌信息,並對這些信息進行多維度的分析視頻直播,使用 MongoDB 存儲用戶信息、禮物信息等......如果你還在爲是否應該使用 MongoDB,不如來做幾個選擇題來輔助決策(注:以下內容改編自 MongoDB 公司 TJ 同學的某次公開技術分享)。應用特徵Yes / No應用不需要事務及複雜 join 支持必須 Yes新應用,需求會變,數據模型無法確定,想快速迭代開發?應用需要2000-3000以上的讀寫QPS(更高也可以)?應用需要TB甚至 PB 級別數據存儲?應用發展迅速,需要能快速水平擴展?應用要求存儲的數據不丟失?應用需要99.999%高可用?應用需要大量的地理位置查詢、文本查詢?如果上述有1個 Yes,可以考慮 MongoDB,2個及以上的 Yes,選擇MongoDB絕不會後悔。

安裝部署

官方文檔

https://docs.mongodb.com/manual/?_ga=2.57024426.1834178963.1557492386-
816165234.1557492386

安裝方式

官方下載地址:
https://www.mongodb.com/download-center/community
tar 包的安裝方式
https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-3.6.13.tgz

目錄規劃

以軟連接形式放在/opt 目錄下

軟件安裝

[root@db01 ~]# yum install libcurl openssl -y
[root@db01 ~]# mkdir /opt/mongo_cluster/ -p
[root@db01 ~]# mkdir /data/soft -p
[root@db01 ~]# cd /data/soft/
[root@db01 /data/soft]# wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-3.6.13.tgz
[root@db01 /data/soft]# tar zxvf mongodb-linux-x86_64-3.6.13.tgz -C /opt/mongo_cluster/
[root@db01 /data/soft]# cd /opt/mongo_cluster/
[root@db01 /opt/mongo_cluster]# ln -s mongodb-linux-x86_64-3.6.13 mongodb
[root@db01 /opt/mongodb_cluster]# mkdir /opt/mongo_cluster/mongo_27017/{conf,logs,pid} -p
[root@db01 /opt/mongodb_cluster]# mkdir /data/mongo_cluster/mongo_27017 -p

配置文件

參考博客
https://blog.csdn.net/MatrixGod/article/details/82585778
配置文解釋:
systemLog:
destination: file #Mongodb 日誌輸出的目的地,指定一個 file 或者 syslog,如果指定 file,必須指定
logAppend: true #當實例重啓時,不創建新的日誌文件,在老的日誌文件末尾繼續添加
path: /opt/mongo_cluster/mongo_27017/logs/mongodb.log #日誌路徑
storage:
journal: #回滾日誌
enabled: true
dbPath: /data/mongo_cluster/mongo_27017 #數據存儲目錄
directoryPerDB: true #默認 false,不適用 inmemory engine
wiredTiger:
engineConfig:
cacheSizeGB: 1 #將用於所有數據緩存的最大小
directoryForIndexes: true #默認false 索引集合storage.dbPath 存儲在數據單獨子目錄
collectionConfig:
blockCompressor: zlib
indexConfig:
prefixCompression: true
processManagement: #使用處理系統守護進程的控制處理
fork: true #後臺運行
pidFilePath: /opt/mongo_cluster/mongo_27017/pid/mongod.pid #創建 pid 文件
net:
port: 27017 #監聽端口
bindIp: 127.0.0.1,10.0.0.51 #綁定 ip


寫入配置文件
[root@db01 ~]# cat > /opt/mongo_cluster/mongo_27017/conf/monogdb.conf << EOF
systemLog:
destination: file
logAppend: true
path: /opt/mongo_cluster/mongo_27017/logs/mongodb.log
storage:
journal:
enabled: true
dbPath: /data/mongo_cluster/mongo_27017
directoryPerDB: true
wiredTiger:
engineConfig:
cacheSizeGB: 1
directoryForIndexes: true
collectionConfig:
blockCompressor: zlib
indexConfig:
prefixCompression: true
processManagement:
fork: true
pidFilePath: /opt/mongo_cluster/mongo_27017/pid/mongod.pid
net:
port: 27017
bindIp: 127.0.0.1,10.0.0.51
EOF

啓動關閉

啓動命令

[root@db01 ~]# /opt/mongodb/bin/mongod -f /opt/mongodb/conf/monogdb.conf
about to fork child process, waiting until server is ready for connections.
forked process: 3024
child process started successfully, parent exiting

檢查命令

[root@db01 ~]# ps -ef|grep mongo
root 3024 1 3 10:26 ? 00:00:00 /opt/mongodb/bin/mongod -f
/opt/mongodb/conf/monogdb.conf
root 3049 1827 0 10:26 pts/0 00:00:00 grep -E --color=auto --color=auto mongo
[root@db01 ~]# netstat -lntup|grep 27017
tcp 0 0 10.0.0.51:27017 0.0.0.0:* LISTEN 3024/mongod
tcp 0 0 127.0.0.1:27017 0.0.0.0:* LISTEN 3024/mongod
[root@db01 ~]# ll /data/mongodb/
總用量 72
drwx------ 4 root root 35 7 月 6 10:26 admin
drwx------ 4 root root 35 7 月 6 10:26 config
drwx------ 2 root root 69 7 月 6 10:27 diagnostic.data
drwx------ 2 root root 107 7 月 6 10:26 journal
drwx------ 4 root root 35 7 月 6 10:26 local
-rw------- 1 root root 16384 7 月 6 10:27 _mdb_catalog.wt
-rw------- 1 root root 5 7 月 6 10:26 mongod.lock
-rw------- 1 root root 4096 7 月 6 10:26 sizeStorer.wt
-rw------- 1 root root 114 7 月 6 10:26 storage.bson
-rw------- 1 root root 45 7 月 6 10:26 WiredTiger
-rw------- 1 root root 4096 7 月 6 10:26 WiredTigerLAS.wt
-rw------- 1 root root 21 7 月 6 10:26 WiredTiger.lock
-rw------- 1 root root 1095 7 月 6 10:27 WiredTiger.turtle
-rw------- 1 root root 28672 7 月 6 10:27 WiredTiger.wt

寫入環境變量

[root@db01 ~]# echo 'PATH=$PATH:/opt/mongodb/bin' >> /etc/profile
[root@db01 ~]# tail -1 /etc/profile
PATH=$PATH:/opt/mongodb/bin
[root@db01 ~]# source /etc/profile
[root@db01 ~]# mongo
mongo mongoexport mongoperf mongos
mongod mongofiles mongoreplay mongostat
mongodump mongoimport mongorestore mongotop

創建hosts解析

[root@db01 ~]# cat > /etc/hosts <<EOF
10.0.0.51 db01
10.0.0.52 db02
10.0.0.53 db03
EOF

連接命令

root@db01 ~]# mongo db01:27017
MongoDB shell version v3.6.13
connecting to: mongodb://db01:27017/test?gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("5dccc8f1-3e0e-4001-9361-4b4d9b6b2a8c") }
MongoDB server version: 3.6.13
Welcome to the MongoDB shell.
For interactive help, type "help".
For more comprehensive documentation, see
http://docs.mongodb.org/
Questions? Try the support group
http://groups.google.com/group/mongodb-user
Server has startup warnings:
2019-07-06T10:26:37.135+0800 I STORAGE [initandlisten]
2019-07-06T10:26:37.135+0800 I STORAGE [initandlisten] ** WARNING: The configured WiredTiger
cache size is more than 80% of available RAM.
2019-07-06T10:26:37.135+0800 I STORAGE [initandlisten] ** See
http://dochub.mongodb.org/core/faq-memory-diagnostics-wt
2019-07-06T10:26:37.751+0800 I CONTROL [initandlisten]
2019-07-06T10:26:37.751+0800 I CONTROL [initandlisten] ** WARNING: Access control is not enabled
for the database.
2019-07-06T10:26:37.751+0800 I CONTROL [initandlisten] ** Read and write access to data
and configuration is unrestricted.
2019-07-06T10:26:37.751+0800 I CONTROL [initandlisten] ** WARNING: You are running this process
as the root user, which is not recommended.
2019-07-06T10:26:37.751+0800 I CONTROL [initandlisten]
2019-07-06T10:26:37.751+0800 I CONTROL [initandlisten]
2019-07-06T10:26:37.751+0800 I CONTROL [initandlisten] ** WARNING:
/sys/kernel/mm/transparent_hugepage/enabled is 'always'.
2019-07-06T10:26:37.751+0800 I CONTROL [initandlisten] ** We suggest setting it to 'never'
2019-07-06T10:26:37.751+0800 I CONTROL [initandlisten]
2019-07-06T10:26:37.751+0800 I CONTROL [initandlisten] ** WARNING:
/sys/kernel/mm/transparent_hugepage/defrag is 'always'.
2019-07-06T10:26:37.751+0800 I CONTROL [initandlisten] ** We suggest setting it to 'never'
2019-07-06T10:26:37.751+0800 I CONTROL [initandlisten]
>

關閉命令

2 種關閉方式,建議使用mongo 自帶的命令
方法1:登陸mongo 使用內置shutdown 命令
使用這條命令的前提是必須使用localhost 登陸,否則會提示報錯
[root@db01 ~]# mongo localhost:27017
> use admin
switched to db admin
> db.shutdownServer()
server should be down...
2019-07-06T10:42:53.538+0800 I NETWORK [thread1] trying reconnect to localhost:27017 (127.0.0.1)
failed
2019-07-06T10:42:53.538+0800 W NETWORK [thread1] Failed to connect to 127.0.0.1:27017,
in(checking socket for error after poll), reason: Connection refused
2019-07-06T10:42:53.538+0800 I NETWORK [thread1] reconnect localhost:27017 (127.0.0.1) failed
failed
>
bye
方法2:啓動命令添加--config 命令
[root@db01 ~]# mongod -f /opt/mongodb/conf/monogdb.conf --shutdown
killing process with pid: 3391

警告優化

普通用戶登錄

高靜內容:
2019-07-06T10:26:37.751+0800 I CONTROL [initandlisten] ** WARNING: You are running this process
as the root user, which is not recommended.
解決方案:
1.創建普通用戶
2.更改目錄權限
3.切換到普通用戶後再啓動mongo
[root@db01 ~]# useradd mongo
[root@db01 ~]# echo '123456'|passwd --stdin mongo
[root@db01 ~]# chown -R mongo:mongo /opt/mongo_cluster
[root@db01 ~]# chown -R mongo:mongo /data/mongo_cluster

關閉大內存頁hugepage

官方網站:
https://docs.mongodb.com/manual/tutorial/transparent-huge-pages/
查看狀態
[root@db01 ~]# cat /sys/kernel/mm/transparent_hugepage/enabled
[always] madvise never
[root@db01 ~]# cat /sys/kernel/mm/transparent_hugepage/defrag
[always] madvise never
臨時關閉命令
[root@db01 ~]# echo never > /sys/kernel/mm/transparent_hugepage/enabled
[root@db01 ~]# echo never > /sys/kernel/mm/transparent_hugepage/defrag
永久關閉命令,用官方的腳本寫入開機自啓動
[root@db01 ~]# cat /etc/init.d/disable-transparent-hugepages
#!/bin/bash
### BEGIN INIT INFO
# Provides: disable-transparent-hugepages
# Required-Start: $local_fs
# Required-Stop:
# X-Start-Before: mongod mongodb-mms-automation-agent
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Disable Linux transparent huge pages
# Description: Disable Linux transparent huge pages, to improve
# database performance.
### END INIT INFO
case $1 in
start)
if [ -d /sys/kernel/mm/transparent_hugepage ]; then
thp_path=/sys/kernel/mm/transparent_hugepage
elif [ -d /sys/kernel/mm/redhat_transparent_hugepage ]; then
thp_path=/sys/kernel/mm/redhat_transparent_hugepage
else
return 0
fi
echo 'never' > ${thp_path}/enabled
echo 'never' > ${thp_path}/defrag
re='^[0-1]+$'
if [[ $(cat ${thp_path}/khugepaged/defrag) =~ $re ]]
then
# RHEL 7
echo 0 > ${thp_path}/khugepaged/defrag
else
# RHEL 6
echo 'no' > ${thp_path}/khugepaged/defrag
fi
unset re
unset thp_path
;;
esac
賦予腳本權限
[root@db01 ~]# chmod 755 /etc/init.d/disable-transparent-hugepages
加入開機自啓動
[root@db01 ~]# chkconfig --add disable-transparent-hugepages
[root@db01 ~]# chkconfig --list|grep disable

內存佔用超過80%

2019-07-06T11:23:16.801+0800 I STORAGE [initandlisten] ** WARNING: The configured WiredTiger cache
size is more than 80% of available RAM.
2019-07-06T11:23:16.801+0800 I STORAGE [initandlisten] ** See
http://dochub.mongodb.org/core/faq-memory-diagnostics-wt
解決方法:
增加內存或者在配置文件裏把cash 調小
[mongo@db01 ~]$ grep "cacheSizeGB" /opt/mongo_cluster/mongo_27017/conf/monogdb.conf
cacheSizeGB: 1

用戶訪問控制

配置文件增加用戶認證的配置參數
security:
authorization: enabled

mongodb默認存在的庫

test:登錄時默認存在的庫
admin 庫:系統預留庫,MongoDB 系統管理庫
local 庫:本地預留庫,存儲關鍵日誌
config 庫:MongoDB 配置信息庫
操作命令:
show databases/show dbs
show tables/show collections
use admin
db/select database()

基本操作

介紹

CRUD 操作是create(創建), read(讀取), update(更新)和delete(刪除) 文檔。
MongoDB 不支持多文檔事務(mongodb4.0 開始支持ACID)。但是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 打印所有可用數據庫的列表。
load() 執行一個JavaScript 文件。

創建索引

默認情況下,創建索引將阻止數據庫上的所有其他操作。在集合上構建索引時,保存集合的數據庫對於讀取或寫
入操作是不可用的,直到索引構建完成。任何需要對所有數據庫(例如listDatabases)進行讀或寫鎖定的操作將
等待前臺索引構建完成。
對於可能需要長時間運行的索引創建操作,可以考慮 background 選項,這樣MongoDB 數據庫在索引創建期
間仍然是可用的。例如,在 people 集合的 zipcode 鍵上創建一個索引,這個過程在後臺運行,可以使用如下
方式:
db.people.createIndex( { zipcode: 1}, {background: true} )
默認MongoDB 索引創建的 background 是 false 。
索引優化: db.test.find({"id":100}).explain()
db.people.createIndex( { zipcode: 1}, {background: true} )
db.inventory.find( { qty: { $lt: 30 } } )
查看執行信息
>db.test.find({"age":{ $lt: 30 }})
{ "_id" : ObjectId("5cd60b69082200657d67d78a"), "name" : "zhangya", "age" : 27, "ad" : "北京市朝陽區" }
{ "_id" : ObjectId("5cd60b69082200657d67d78b"), "name" : "zhangya", "age" : 27, "ad" : "北京市朝陽區" }
{ "_id" : ObjectId("5cd60b69082200657d67d78c"), "name" : "yazhang", "age" : 28, "ad" : "北京市朝陽區" }
{ "_id" : ObjectId("5cd60b69082200657d67d78d"), "name" : "xiaozhang", "age" : 28, "ad" : "北京市朝陽區
" }
{ "_id" : ObjectId("5cd60b69082200657d67d78e"), "name" : "xiaozhang", "age" : 28, "ad" : "北京市朝陽區",
"sex" : "boy" }
> db.test.find({"age":{ $lt: 30 }}).explain()
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "test.test",
"indexFilterSet" : false,
"parsedQuery" : {
"age" : {
"$lt" : 30
}
},
"winningPlan" : {
"stage" : "COLLSCAN",
"filter" : {
"age" : {
"$lt" : 30
}
},
"direction" : "forward"
},
"rejectedPlans" : [ ]
},
"serverInfo" : {
"host" : "mongo01",
"port" : 27017,
"version" : "3.4.20",
"gitVersion" : "447847d93d6e0a21b018d5df45528e815c7c13d8"
},
"ok" : 1
}
創建索引
> db.test.createIndex( { age: 1 } )
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 2,
"numIndexesAfter" : 3,
"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: 30 }}).explain()
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "test.test",
"indexFilterSet" : false,
"parsedQuery" : {
"age" : {
"$lt" : 30
}
},
"winningPlan" : {
"stage" : "FETCH",
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"age" : 1
},
"indexName" : "age_1",
"isMultiKey" : false,
"multiKeyPaths" : {
"age" : [ ]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"age" : [
"[-inf.0, 30.0)"
]
}
}
},
"rejectedPlans" : [ ]
},
"serverInfo" : {
"host" : "mongo01",
"port" : 27017,
"version" : "3.4.20",
"gitVersion" : "447847d93d6e0a21b018d5df45528e815c7c13d8"
},
"ok" : 1
}
刪除索引
> db.test.dropIndex({ name: 1 } )
{ "nIndexesWas" : 3, "ok" : 1 }

插入數據

官方文檔

https://docs.mongodb.com/guides/server/read_queries/

單行插入

命令集合
db.test.insert({"name":"zhangya","age":27,"ad":"北京市朝陽區"})
db.test.insert({"name":"zhangya","age":27,"ad":"北京市朝陽區"})
db.test.insert({"name":"yazhang","age":28,"ad":"北京市朝陽區"})
db.test.insert({"name":"xiaozhang","age":28,"ad":"北京市朝陽區"})
db.test.insert({"name":"xiaozhang","age":28,"ad":"北京市朝陽區","sex":"boy"})
執行結果;
> db.test.insert({"name":"zhangya","age":27,"ad":"北京市朝陽區"})
WriteResult({ "nInserted" : 1 })
> db.test.insert({"name":"zhangya","age":27,"ad":"北京市朝陽區"})
WriteResult({ "nInserted" : 1 })
> db.test.insert({"name":"yazhang","age":28,"ad":"北京市朝陽區"})
WriteResult({ "nInserted" : 1 })
> db.test.insert({"name":"xiaozhang","age":28,"ad":"北京市朝陽區"})
WriteResult({ "nInserted" : 1 })
> db.test.insert({"name":"xiaozhang","age":28,"ad":"北京市朝陽區","sex":"boy"})
WriteResult({ "nInserted" : 1 })

多行插入

官網舉例命令集合:
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("5cd60d2c082200657d67d78f"),
ObjectId("5cd60d2c082200657d67d790"),
ObjectId("5cd60d2c082200657d67d791"),
ObjectId("5cd60d2c082200657d67d792"),
ObjectId("5cd60d2c082200657d67d793")
]
}

查詢數據

查詢所有

> db.test.find()
{ "_id" : ObjectId("5cd60b69082200657d67d78a"), "name" : "zhangya", "age" : 27, "ad" : "北京市朝陽區" }
{ "_id" : ObjectId("5cd60b69082200657d67d78b"), "name" : "zhangya", "age" : 27, "ad" : "北京市朝陽區" }
{ "_id" : ObjectId("5cd60b69082200657d67d78c"), "name" : "yazhang", "age" : 28, "ad" : "北京市朝陽區" }
{ "_id" : ObjectId("5cd60b69082200657d67d78d"), "name" : "xiaozhang", "age" : 28, "ad" : "北京市朝陽區
" }
{ "_id" : ObjectId("5cd60b69082200657d67d78e"), "name" : "xiaozhang", "age" : 28, "ad" : "北京市朝陽區",
"sex" : "boy" }

查詢單條

> db.test.findOne()
{
"_id" : ObjectId("5cd60b69082200657d67d78a"),
"name" : "zhangya",
"age" : 27,
"ad" : "北京市朝陽區"
}

條件查詢

官網舉例1:
> myCursor = db.inventory.find( { status: "D" } )
{ "_id" : ObjectId("5cd60d2c082200657d67d791"), "item" : "paper", "qty" : 100, "size" : { "h" : 8.5, "w" : 11,
"uom" : "in" }, "status" : "D" }
{ "_id" : ObjectId("5cd60d2c082200657d67d792"), "item" : "planner", "qty" : 75, "size" : { "h" : 22.85, "w" :
30, "uom" : "cm" }, "status" : "D" }
官網舉例2:
> myCursor = db.inventory.find( { "size.uom": "in" } )
{ "_id" : ObjectId("5cd60d2c082200657d67d790"), "item" : "notebook", "qty" : 50, "size" : { "h" : 8.5, "w" :
11, "uom" : "in" }, "status" : "A" }
{ "_id" : ObjectId("5cd60d2c082200657d67d791"), "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("5cd60d2c082200657d67d78f"), "item" : "journal", "qty" : 25, "size" : { "h" : 14, "w" : 21,
"uom" : "cm" }, "status" : "A" }
> db.inventory.find( { "size.h":{$gt:10}, "qty":75 } )
{ "_id" : ObjectId("5d22c9c03c6524dfb1de89b5"), "item" : "planner", "qty" : 75, "size" : { "h" : 22.85, "w" :
30, "uom" : "cm" }, "status" : "D" }
官網舉例4: or
> myCursor = db.inventory.find( { $or: [ { status: "A" }, { qty: { $lt: 30 } } ] } )
{ "_id" : ObjectId("5cd60d2c082200657d67d78f"), "item" : "journal", "qty" : 25, "size" : { "h" : 14, "w" : 21,
"uom" : "cm" }, "status" : "A" }
{ "_id" : ObjectId("5cd60d2c082200657d67d790"), "item" : "notebook", "qty" : 50, "size" : { "h" : 8.5, "w" :
11, "uom" : "in" }, "status" : "A" }
{ "_id" : ObjectId("5cd60d2c082200657d67d793"), "item" : "postcard", "qty" : 45, "size" : { "h" : 10, "w" :
15.25, "uom" : "cm" }, "status" : "A" }
官網舉例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("5cd60d2c082200657d67d78f"), "item" : "journal", "qty" : 25, "size" : { "h" : 14, "w" : 21,
"uom" : "cm" }, "status" : "A" }
{ "_id" : ObjectId("5cd60d2c082200657d67d793"), "item" : "postcard", "qty" : 45, "size" : { "h" : 10, "w" :
15.25, "uom" : "cm" }, "status" : "A" }
>

查看數據庫命令

> show dbs
admin 0.000GB
local 0.000GB
test 0.000GB
test2 0.000GB
> use test
switched to db test
> db
test
> show collections
inventory
test

更新數據

更新單個文檔

命令:
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("5cd60d2c082200657d67d791"), "item" : "paper", "qty" : 100, "size" : { "h" : 8.5, "w" : 11,
"uom" : "cm" }, "status" : "P", "lastModified" : ISODate("2019-05-10T23:56:18.954Z") }

更新多條數據

執行命令:
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("5cd60d2c082200657d67d78f"), "item" : "journal", "qty" : 25, "size" : { "h" : 14, "w" : 21,
"uom" : "cm" }, "status" : "P", "lastModified" : ISODate("2019-05-10T23:59:01.922Z") }
{ "_id" : ObjectId("5cd60d2c082200657d67d793"), "item" : "postcard", "qty" : 45, "size" : { "h" : 10, "w" :
15.25, "uom" : "cm" }, "status" : "P", "lastModified" : ISODate("2019-05-10T23:59:01.922Z") }

刪除數據

刪除單條文檔

官方文檔
https://docs.mongodb.com/guides/server/delete/
查詢結果
> myCursor = db.inventory.find( { "status": "D" } )
{ "_id" : ObjectId("5cd60d2c082200657d67d792"), "item" : "planner", "qty" : 75, "size" : { "h" : 22.85, "w" :
30, "uom" : "cm" }, "status" : "D" }
操作命令
use test
db.inventory.deleteOne(
{ "status": "D" } // specifies the document to delete
)
返回結果
> db.inventory.deleteOne(
... { "status": "D" } // specifies the document to delete
... )
{ "acknowledged" : true, "deletedCount" : 1 }
再次查詢
> myCursor = db.inventory.find( { "status": "D" } )
>

刪除多條文檔

查詢數據
> myCursor = db.inventory.find( { "status": "P" } )
{ "_id" : ObjectId("5cd60d2c082200657d67d78f"), "item" : "journal", "qty" : 25, "size" : { "h" : 14, "w" : 21,
"uom" : "cm" }, "status" : "P", "lastModified" : ISODate("2019-05-10T23:59:01.922Z") }
{ "_id" : ObjectId("5cd60d2c082200657d67d791"), "item" : "paper", "qty" : 100, "size" : { "h" : 8.5, "w" : 11,
"uom" : "cm" }, "status" : "P", "lastModified" : ISODate("2019-05-10T23:56:18.954Z") }
{ "_id" : ObjectId("5cd60d2c082200657d67d793"), "item" : "postcard", "qty" : 45, "size" : { "h" : 10, "w" :
15.25, "uom" : "cm" }, "status" : "P", "lastModified" : ISODate("2019-05-10T23:59:01.922Z") }
操作命令
db.inventory.deleteMany(
{ "status" : "P" } // specifies the documents to delete
)
返回結果
> db.inventory.deleteMany(
... { "status" : "P" } // specifies the documents to delete
... )
{ "acknowledged" : true, "deletedCount" : 3 }
再次查看數據
> myCursor = db.inventory.find( { "status": "P" } )
>

工具介紹

官網地址

https://docs.mongodb.com/manual/reference/program/

mongod

Mongod 是Mongodb 系統的主要守護進程,它處理數據請求,管理數據訪問,並執行後臺
管理操作。啓動進程指定配置文件,控制數據庫的行爲

mongos

mongos 對於“ MongoDB Shard”,是用於處理來自應用層的查詢的MongoDB 分片配置的路由服務,並確
定此數據在分片集羣中的位置, 以完成這些操作。從應用程序的角度來看,一個 mongos 實例與任何其他
MongoDB 實例的行爲相同。

mongostat

Mongostat 實用程序可以快速概覽當前正在運行的mongod 或mongos 實例的狀態。mongostat 在功能上類
似於UNIX / Linux 文件系統實用程序vmstat,但提供有關的數據 mongod 和mongos 實例

Mongotop

Mongotop 提供了一種跟蹤MongoDB 實例讀取和寫入數據的時間量的方法。 mongotop 提供每個收集級別
的統計信息。默認情況下,mongotop 每秒返回一次值

Mongooplog

Mongooplog 是一個簡單的工具,可以從遠程服務器的複製 oplog 輪詢操作,並將其應用於本地服務器。此功
能支持某些類型的實時遷移,這些遷移要求源服務器保持聯機並在整個遷移過程中運行。通常,此命令將採用以
下形式:
mongooplog - from mongodb0.example.net --host mongodb1.example.net

Mongooplog

Mongoperf 是一種獨立於MongoDB 檢查磁盤I / O 性能的實用程序。它是隨機磁盤I / O 的測試並呈現結果。
例如:
echo "{nThreads:16, fileSizeMB:10000, r:true, w:true}"| mongoperf
在這個操作中:
mongoperf 測試直接物理隨機讀寫io 的,使用16 個併發閱讀器線程。
mongoperf 使用10 GB 的測試文件。
或者參數寫入文件裏 mongoperf < config

授權認證

官方網址

https://docs.mongodb.com/manual/reference/configuration-options/#security-options
https://docs.mongodb.com/manual/tutorial/enable-authentication/

授權介紹

用戶管理界面
要添加用戶, 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() 更新用戶數據。

創建用戶和角色

創建命令
[mongo@db01 ~]$ mongo db01:27017
> 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"
}
]
}
]
>

配置文件

security: #認證
authorization: enabled #啓用或者禁用基於角色的訪問控制來管理每個用戶對數據庫資源和操作的訪問
enabled 或者 disables

使用賬號密碼連接

配置問權限認證後需要重啓節點,再次登陸如果不使用賬號密碼就查看不了數據
[mongo@db01 ~]$ mongo db01:27017
> show dbs
2019-07-06T11:43:14.047+0800 E QUERY [thread1] Error: listDatabases failed:{
"ok" : 0,
"errmsg" : "there are no users authenticated",
"code" : 13,
"codeName" : "Unauthorized"
} :
_getErrorWithCode@src/mongo/shell/utils.js:25:13
Mongo.prototype.getDBs@src/mongo/shell/mongo.js:67:1
shellHelper.show@src/mongo/shell/utils.js:860:19
shellHelper@src/mongo/shell/utils.js:750:15
@(shellhelp2):1:1
使用賬號密碼登陸:
[mongo@db01 ~]$ mongo db01:27017 -u admin -p
MongoDB shell version v3.6.13
Enter password:
> show dbs
admin 0.000GB
config 0.000GB
local 0.000GB
test 0.000GB
[mongo@db01 ~]$ mongo db01:27017 -u admin -p
Enter password:
> show dbs
admin 0.000GB
config 0.000GB
local 0.000GB
test 0.000GB
> db.test.find()
{ "_id" : ObjectId("5d2016396e91339718e18f95"), "name" : "zhangya", "age" : 27, "ad" : "北京市朝陽區" }
{ "_id" : ObjectId("5d2016396e91339718e18f96"), "name" : "zhangya", "age" : 27, "ad" : "北京市朝陽區" }
{ "_id" : ObjectId("5d2016396e91339718e18f97"), "name" : "yazhang", "age" : 28, "ad" : "北京市朝陽區" }
{ "_id" : ObjectId("5d2016396e91339718e18f98"), "name" : "xiaozhang", "age" : 28, "ad" : "北京市朝陽區" }
{ "_id" : ObjectId("5d2016396e91339718e18f99"), "name" : "xiaozhang", "age" : 28, "ad" : "北京市朝陽區",
"sex" : "boy" }
設置不同賬號權限
use test
db.createUser(
{
user: "myTester",
pwd: "xyz123",
roles: [ { role: "readWrite", db: "test" },
{ role: "read", db: "test2" } ]
}
)
執行結果
> db.createUser(
... {
... user: "myTester",
... pwd: "xyz123",
... roles: [ { role: "readWrite", db: "test" },
... { role: "read", db: "test2" } ]
... }
... )
Successfully added user: {
"user" : "myTester",
"roles" : [
{
"role" : "readWrite",
"db" : "test"
},
{
"role" : "read",
"db" : "test2"
}
]
}
登陸查看
> use test
switched to db test
> db.auth("myTester","xyz123")
1
> show collections
inventory
test
驗證可讀
> db.test.findOne()
{
"_id" : ObjectId("5cd60b69082200657d67d78a"),
"name" : "zhangya",
"age" : 27,
"ad" : "北京市朝陽區"
}
> db.inventory.findOne()
{
"_id" : ObjectId("5cd638a71a9c2b8c9274568b"),
"item" : "journal",
"qty" : 25,
"size" : {
"h" : 14,
"w" : 21,
"uom" : "cm"
},
"status" : "A"
}
驗證可寫
> db.test.insertOne({"name":"xiaozhang","age":30,"ad":"北京市朝陽區"})
{
"acknowledged" : true,
"insertedId" : ObjectId("5cd63c5d5f928a68501b0bf0")
db.inventory.insertOne(
{ item: "canvas", qty: 100, tags: ["cotton"], size: { h: 28, w: 35.5, uom: "cm" } }
)
切換到test2 庫,發現可讀不可寫
> use test2
> db.inventory.findOne()
{
"_id" : ObjectId("5cd6392c1a9c2b8c92745690"),
"item" : "journal",
"qty" : 25,
"size" : {
"h" : 14,
"w" : 21,
"uom" : "cm"
},
"status" : "A"
}
> db.inventory.insertOne( { item: "canvas", qty: 100, tags: ["cotton"], size: { h: 28, w: 35.5, uom:
"cm" } } )
2019-05-11T11:24:05.120+0800 E QUERY [thread1] TypeError: err.hasWriteErrors is not a function :
DBCollection.prototype.insertOne@src/mongo/shell/crud_api.js:244:13
@(shell):1:1

副本集配置

官方網站

https://docs.mongodb.com/manual/tutorial/deploy-replica-set/

副本集介紹

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-I18ZiPzp-1576240067786)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1576215977073.png)]

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-OmBRbRtK-1576240067796)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1576216014315.png)]

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-5uuBdUzL-1576240067799)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1576216038288.png)]

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-NUiRHJj5-1576240067801)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1576216070467.png)]

目錄規劃

以/opt/mongo+端口號爲單機多實例存放目錄

創建多實例目錄

[root@db01 ~]# mkdir -p /opt/mongo_cluster/mongo_2801{7,8,9}/{conf,logs,pid}
[root@db01 ~]# tree /opt/ -L 2
/opt/
├── mongodb -> mongodb-linux-x86_64-3.6.13
├── mongodb28017
│ ├── conf
│ ├── logs
│ └── pid
├── mongodb28018
│ ├── conf
│ ├── logs
│ └── pid
├── mongodb28019
│ ├── conf
│ ├── logs
│ └── pid
└── mongodb-linux-x86_64-3.6.13
├── bin
├── conf
├── LICENSE-Community.txt
├── logs
├── MPL-2
├── pid
├── README
├── THIRD-PARTY-NOTICES
└── THIRD-PARTY-NOTICES.gotools
18 directories, 5 files

創建配置文件

[root@db01 ~]# cat >/opt/mongo_cluster/mongo_28017/conf/mongo_28017.conf <<EOF
systemLog:
destination: file
logAppend: true
path: /opt/mongo_cluster/mongo_28017/logs/mongodb.log
storage:
journal:
enabled: true
dbPath: /data/mongo_cluster/mongo_28017
directoryPerDB: true
wiredTiger:
engineConfig:
cacheSizeGB: 0.5
directoryForIndexes: true
collectionConfig:
blockCompressor: zlib
indexConfig:
prefixCompression: true
processManagement:
fork: true
pidFilePath: /opt/mongo_cluster/mongo_28017/pid/mongod.pid
net:
port: 28017
bindIp: 127.0.0.1,10.0.0.51
security:
authorization: enabled
replication:
oplogSizeMB: 1024
replSetName: dba58
EOF
[root@db01 ~]# cp /opt/mongo_cluster/mongo_28017/conf/mongo_28017.conf
/opt/mongo_cluster/mongo_28018/conf/mongo_28018.conf
[root@db01 ~]# cp /opt/mongo_cluster/mongo_28017/conf/mongo_28017.conf
/opt/mongo_cluster/mongo_28019/conf/mongo_28019.conf
[root@db01 ~]# sed -i 's#28017#28018#g' /opt/mongo_cluster/mongo_28018/conf/mongo_28018.conf
[root@db01 ~]# sed -i 's#28017#28019#g' /opt/mongo_cluster/mongo_28019/conf/mongo_28019.conf

創建數據目錄

[root@db01 ~]# mkdir /data/mongo_cluster/mongo_2801{7,8,9}
[root@db01 ~]# tree /data/ -L 1
/data/
├── mongodb
├── mongodb28017
├── mongodb28018
├── mongodb28019
└── soft

更改目錄權限

[root@db01 ~]# chown -R mongo:mongo /data/mongo_cluster
[root@db01 ~]# chown -R mongo:mongo /opt/mongo_cluster

啓動所有節點

[mongo@db01 ~]$ mongod -f /opt/mongo_cluster/mongo_28017/conf/mongo_28017.conf
[mongo@db01 ~]$ mongod -f /opt/mongo_cluster/mongo_28018/conf/mongo_28018.conf
[mongo@db01 ~]$ mongod -f /opt/mongo_cluster/mongo_28019/conf/mongo_28019.conf

初始化副本集

初始化命令:
config = {
_id : "dba58",
members : [
{_id : 0, host : " db01:28017"},
{_id : 1, host : " db01:28018"},
{_id : 2, host : " db01:28019"},
] }
rs.initiate(config)
執行過程
[mongo@db01 ~]$ mongo db01:28017
> config = {
... _id : "dba58",
... members : [
... {_id : 0, host : " db01:28017"},
... {_id : 1, host : " db01:28018"},
... {_id : 2, host : " db01:28019"},
... ] }
{
"_id" : "dba58",
"members" : [
{
"_id" : 0,
"host" : " db01:28017"
},
{
"_id" : 1,
"host" : " db01:28018"
},
{
"_id" : 2,
"host" : " db01:28019"
}
]
}
> rs.initiate(config)
{
"ok" : 1,
"operationTime" : Timestamp(1562403735, 1),
"$clusterTime" : {
"clusterTime" : Timestamp(1562403735, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
}
}
dba58:SECONDARY>
dba58:PRIMARY>

查看狀態

dba58:PRIMARY> rs.status()

寫入測試數據

命令:
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" }
]);
執行過程:
dba58: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" }
... ]);
{
"acknowledged" : true,
"insertedIds" : [
ObjectId("5d20644ec990c165b34fcc58"),
ObjectId("5d20644ec990c165b34fcc59"),
ObjectId("5d20644ec990c165b34fcc5a"),
ObjectId("5d20644ec990c165b34fcc5b"),
ObjectId("5d20644ec990c165b34fcc5c")
]
}
dba58:PRIMARY> db.inventory.find()
{ "_id" : ObjectId("5d20644ec990c165b34fcc58"), "item" : "journal", "qty" : 25, "size" : { "h" : 14, "w" : 21,
"uom" : "cm" }, "status" : "A" }
{ "_id" : ObjectId("5d20644ec990c165b34fcc59"), "item" : "notebook", "qty" : 50, "size" : { "h" : 8.5, "w" :
11, "uom" : "in" }, "status" : "A" }
{ "_id" : ObjectId("5d20644ec990c165b34fcc5a"), "item" : "paper", "qty" : 100, "size" : { "h" : 8.5, "w" : 11,
"uom" : "in" }, "status" : "D" }
{ "_id" : ObjectId("5d20644ec990c165b34fcc5b"), "item" : "planner", "qty" : 75, "size" : { "h" : 22.85, "w" :
30, "uom" : "cm" }, "status" : "D" }
{ "_id" : ObjectId("5d20644ec990c165b34fcc5c"), "item" : "postcard", "qty" : 45, "size" : { "h" : 10, "w" :
15.25, "uom" : "cm" }, "status" : "A" }

驗證副本是否同步

dba58:SECONDARY> db.inventory.find()
Error: error: {
"operationTime" : Timestamp(1562404003, 4),
"ok" : 0,
"errmsg" : "not master and slaveOk=false",
"code" : 13435,
"codeName" : "NotMasterNoSlaveOk",
"$clusterTime" : {
"clusterTime" : Timestamp(1562404003, 4),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
}
}
這裏會提示副本不可讀,通過命令配置副本可讀
dba58:SECONDARY> rs.slaveOk();
再次查看
dba58:SECONDARY> db.inventory.find()
{ "_id" : ObjectId("5d20644ec990c165b34fcc58"), "item" : "journal", "qty" : 25, "size" : { "h" : 14, "w" : 21,
"uom" : "cm" }, "status" : "A" }
{ "_id" : ObjectId("5d20644ec990c165b34fcc59"), "item" : "notebook", "qty" : 50, "size" : { "h" : 8.5, "w" :
11, "uom" : "in" }, "status" : "A" }
{ "_id" : ObjectId("5d20644ec990c165b34fcc5b"), "item" : "planner", "qty" : 75, "size" : { "h" : 22.85, "w" :
30, "uom" : "cm" }, "status" : "D" }
{ "_id" : ObjectId("5d20644ec990c165b34fcc5a"), "item" : "paper", "qty" : 100, "size" : { "h" : 8.5, "w" : 11,
"uom" : "in" }, "status" : "D" }
{ "_id" : ObjectId("5d20644ec990c165b34fcc5c"), "item" : "postcard", "qty" : 45, "size" : { "h" : 10, "w" :
15.25, "uom" : "cm" }, "status" : "A" }
嘗試刪除
dba58:SECONDARY> db.inventory.remove({})
WriteResult({ "writeError" : { "code" : 10107, "errmsg" : "not master" } })

故障轉移

將主節點殺掉
[mongo@db01 ~]$ mongod -f /opt/mongo_cluster/mongo_28017/conf/mongo_28017.conf --
shutdown
killing process with pid: 3847
登陸副本節點查看
[mongo@db01 ~]$ mongo db01:28019
dba58:PRIMARY>
嘗試修改數據
dba58:PRIMARY> db.test.insert({"name":"zhangya","age":27,"ad":"北京市朝陽區"})
WriteResult({ "nInserted" : 1 })
dba58:PRIMARY> db.test.find()
{ "_id" : ObjectId("5d2091fc89c7e9177a03e785"), "name" : "zhangya", "age" : 27, "ad" : "北京市朝陽區" }
在從庫上查看
[mongo@db01 ~]$ mongo db01:28018
dba58:SECONDARY> rs.slaveOk();
dba58:SECONDARY> db.test.find()
{ "_id" : ObjectId("5d2091fc89c7e9177a03e785"), "name" : "zhangya", "age" : 27, "ad" : "北京市朝陽區" }
重新啓動損壞節點
[mongo@db01 ~]$ mongod -f /opt/mongo_cluster/mongo_28017/conf/mongo_28017.conf
登陸查看數據
[mongo@db01 ~]$ mongo db01:28017
dba58:SECONDARY> rs.slaveOk();
dba58:SECONDARY> db.test.find()
{ "_id" : ObjectId("5d2091fc89c7e9177a03e785"), "name" : "zhangya", "age" : 27, "ad" : "北京市朝陽區" }

副本集權重調整

如果初始化進羣的時候沒有設置權重,那麼默認每個節點的權重都是一樣的,也就是說每個節點都
可以競選主節點。

查看集羣配置

[mongo@db01 ~]$ mongo db01:28019
dba58:PRIMARY> rs.conf()
{
"_id" : "dba58",
"version" : 1,
"protocolVersion" : NumberLong(1),
"members" : [
{
"_id" : 0,
"host" : "db01:28017",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 1,
"tags" : {
},
"slaveDelay" : NumberLong(0),
"votes" : 1
},
{
"_id" : 1,
"host" : "db01:28018",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 1,
"tags" : {
},
"slaveDelay" : NumberLong(0),
"votes" : 1
},
{
"_id" : 2,
"host" : "db01:28019",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 1,
"tags" : {
},
"slaveDelay" : NumberLong(0),
"votes" : 1
}
],
"settings" : {
"chainingAllowed" : true,
"heartbeatIntervalMillis" : 2000,
"heartbeatTimeoutSecs" : 10,
"electionTimeoutMillis" : 10000,
"catchUpTimeoutMillis" : -1,
"catchUpTakeoverDelayMillis" : 30000,
"getLastErrorModes" : {
},
"getLastErrorDefaults" : {
"w" : 1,
"wtimeout" : 0
},
"replicaSetId" : ObjectId("5d206397091c6674936c8cd7")
}
}

調整節點權重

dba58:PRIMARY> config = rs.conf()
dba58:PRIMARY> config.members[0].priority=100
100
dba58:PRIMARY> rs.reconfig(config)
{
"ok" : 1,
"operationTime" : Timestamp(1562417568, 1),
"$clusterTime" : {
"clusterTime" : Timestamp(1562417568, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
}
}
dba58:SECONDARY>

主節點主動降級

dba58:PRIMARY> rs.stepDown()

增加新節點

創建新節點目錄及啓動
[mongo@db01 ~]$ mkdir /opt/mongo_cluster/mongo_28010/{conf,logs,pid} -p
[mongo@db01 ~]$ mkdir /data/mongo_cluster/mongo_28010
[mongo@db01 ~]$ cp /opt/mongo_cluster/mongo_28017/conf/mongo_28017.conf
/opt/mongo_cluster/mongo_28010/conf/mongo_28010.conf
[mongo@db01 ~]$ sed -i 's#28017#28010#g'
/opt/mongo_cluster/mongo_28010/conf/mongo_28010.conf
[mongo@db01 ~]$ mongod -f /opt/mongo_cluster/mongo_28010/conf/mongo_28010.conf
[mongo@db01 ~]$ mongo db01:28010
>
增加新節點命令,主庫操作
[mongo@db01 ~]$ mongo db01:28017
dba58:PRIMARY> use admin
dba58:PRIMARY> rs.add("db01:28010")
{
"ok" : 1,
"operationTime" : Timestamp(1562420341, 1),
"$clusterTime" : {
"clusterTime" : Timestamp(1562420341, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
}
}
查看新增加節點
[mongo@db01 ~]$ mongo db01:28010
dba58:SECONDARY>

刪除舊節點

主節點操作
[mongo@db01 ~]$ mongo db01:28017
dba58:PRIMARY> rs.remove("db01:28010")
{
"ok" : 1,
"operationTime" : Timestamp(1562420521, 1),
"$clusterTime" : {
"clusterTime" : Timestamp(1562420521, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
}
}
再次查看下線節點
[mongo@db01 ~]$ mongo db01:28010
dba58:OTHER>
現在可以關閉節點了
[mongo@db01 ~]$ mongod -f /opt/mongo_cluster/mongo_28010/conf/mongo_28010.conf --
shutdown

增加仲裁節點

官方地址:
https://docs.mongodb.com/manual/tutorial/add-replica-set-arbiter/
Arbiter 節點只參與投票,不能被選爲Primary,並且不從Primary 同步數據。
清空28010 節點的數據
[mongo@db01 ~]$ rm -rf /data/mongo_cluster/mongo_28010/*
重新啓動
[mongo@db01 ~]$ mongod -f /opt/mongo_cluster/mongo_28010/conf/mongo_28010.conf
檢查
[mongo@db01 ~]$ mongo db01:28010
主庫操作
[mongo@db01 ~]$ mongo db01:28017
dba58:PRIMARY> rs.addArb("db01:28010")
{
"ok" : 1,
"operationTime" : Timestamp(1562421119, 1),
"$clusterTime" : {
"clusterTime" : Timestamp(1562421119, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
}
}
查看集羣狀態
dba58:PRIMARY> rs.status()
.....................................................
{
"_id" : 3,
"name" : "db01:28010",
"health" : 1,
"state" : 7,
"stateStr" : "ARBITER",
"uptime" : 1305,
"lastHeartbeat" : ISODate("2019-07-06T14:13:44.757Z"),
"lastHeartbeatRecv" : ISODate("2019-07-06T14:13:44.735Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "",
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"infoMessage" : "",
"configVersion" : 5
}
查看節點狀態
[mongo@db01 ~]$ mongo db01:28010
dba58:ARBITER>

備份恢復

備份恢復工具介紹

(1)mongoexport/mongoimport
(2)mongodump/mongorestore

備份工具區別在哪裏

應用場景總結:
1、異構平臺遷移 mysql <---> mongodb
2、同平臺,跨大版本:mongodb 2 ----> mongodb 3
mongoexport/mongoimport:json csv
日常備份恢復時使用.
mongodump/mongorestore

導出工具mongoexport

mongoexport 具體用法如下所示:
$ mongoexport --help
參數說明:
-h:指明數據庫宿主機的IP
-u:指明數據庫的用戶名
-p:指明數據庫的密碼
-d:指明數據庫的名字
-c:指明collection 的名字
-f:指明要導出那些列
-o:指明到要導出的文件名
-q:指明導出數據的過濾條件
--authenticationDatabase admin
舉例:
1.單表備份至json 格式
mongoexport -uroot -proot123 --port 27017 --authenticationDatabase admin -d oldboy -c log -o
/mongodb/log.json
注:備份文件的名字可以自定義,默認導出了JSON 格式的數據。
2. 單表備份至csv 格式
如果我們需要導出CSV 格式的數據,則需要使用----type=csv 參數:
mongoexport -uroot -proot123 --port 27017 --authenticationDatabase admin -d test -c log --type=csv
-f uid,name,age,date -o /mongodb/log.csv

導入工具

$ mongoimport --help
參數說明:
-h:指明數據庫宿主機的IP
-u:指明數據庫的用戶名
-p:指明數據庫的密碼
-d:指明數據庫的名字
-c:指明collection 的名字
-f:指明要導入那些列
-j, --numInsertionWorkers=<number> number of insert operations to run concurrently
(defaults to 1)
//並行
數據恢復:
1.恢復json 格式表數據到log1
mongoimport -uroot -proot123 --port 27017 --authenticationDatabase admin -d oldboy -c log1
/mongodb/log.json
2.恢復csv 格式的文件到log2
上面演示的是導入JSON 格式的文件中的內容,如果要導入CSV 格式文件中的內容,則需要通過--type 參數指定導
入格式,具體如下所示:
錯誤的恢復
注意:
(1)csv 格式的文件頭行,有列名字
mongoimport -uroot -proot123 --port 27017 --authenticationDatabase admin -d oldboy -c log2 --
type=csv --headerline --file /mongodb/log.csv
(2)csv 格式的文件頭行,沒有列名字
mongoimport -uroot -proot123 --port 27017 --authenticationDatabase admin -d oldboy -c log3 --
type=csv -f id,name,age,date --file /mongodb/log.csv
--headerline:指明第一行是列名,不需要導入。

異構平臺遷移案例

1.安裝數據庫
[root@db01 ~]# yum install mariadb mariadb-server -y
2.開啓安全路徑
cat > /etc/my.cnf << EOF
secure-file-priv=/tmp
3.重啓數據庫
[root@db01 ~]# systemctl restart mariadb.service
4.導入城市數據
[root@db01 ~]# mysql
MariaDB [(none)]> source /root/world.sql
5.將樣本數據導出成csv 格式
MariaDB [world]> select * from world.city into outfile '/tmp/city1.csv' fields terminated by ',';
6.查看錶結構
MariaDB [(none)]> desc world.city;
+-------------+----------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+----------+------+-----+---------+----------------+
| ID | int(11) | NO | PRI | NULL | auto_increment |
| Name | char(35) | NO | | | |
| CountryCode | char(3) | NO | MUL | | |
| District | char(20) | NO | | | |
| Population | int(11) | NO | | 0 | |
+-------------+----------+------+-----+---------+----------------+
5 rows in set (0.00 sec)
7.處理備份文件
vim /tmp/city.csv ### 添加第一行列名信息
ID,Name,CountryCode,District,Population
8.在mongodb 中導入備份
[root@db01 ~]# su - mongo
[mongo@db01 ~]$ mongoimport --port 28017 -d world -c city --type=csv -f
ID,Name,CountryCode,District,Population --file /tmp/city1.csv
2019-07-07T21:00:26.473+0800 connected to: localhost:28017
2019-07-07T21:00:26.626+0800 imported 4080 documents
9.查看數據
[mongo@db01 ~]$ mongo db01:28017
dba58:PRIMARY> show dbs
admin 0.000GB
config 0.000GB
local 0.001GB
test 0.000GB
world 0.000GB
dba58:PRIMARY> use world
switched to db world
dba58:PRIMARY> db.city.find({CountryCode:"CHN"});

mongodump和mongorestore

1.介紹:
mongodump 能夠在Mongodb 運行時進行備份,它的工作原理是對運行的Mongodb 做查詢,然後將所有查到的文檔寫
入磁盤。
但是存在的問題時使用mongodump 產生的備份不一定是數據庫的實時快照,如果我們在備份時對數據庫進行了寫
入操作,則備份出來的文件可能不完全和Mongodb 實時數據相等。另外在備份時可能會對其它客戶端性能產生不
利的影響。
2.使用方法:
$ mongodump --help
參數說明:
-h:指明數據庫宿主機的IP
-u:指明數據庫的用戶名
-p:指明數據庫的密碼
-d:指明數據庫的名字
-c:指明collection 的名字
-o:指明到要導出的文件名
-q:指明導出數據的過濾條件
-j, --numParallelCollections= number of collections to dump in parallel (4 by default)
--oplog 備份的同時備份oplog
3.mongodump 和mongorestore 基本使用
全庫備份
[root@db01 ~]# mkdir /data/backup
[root@db01 ~]# chown -R mongo:mongo /data/backup/
[root@db01 ~]# su - mongo
[mongo@db01 ~]$ mongodump --port 28017 -o /data/backup
備份word 庫
[mongo@db01 ~]$ mongodump --port 28017 -d world -o /data/backup
壓縮備份
[mongo@db01 ~]$ mongodump --port 28017 -o /data/backup --gzip
[mongo@db01 ~]$ mongodump --port 28017 -d world -o /data/backup --gzip
恢復world 庫
dba58:PRIMARY> show dbs
admin 0.000GB
config 0.000GB
local 0.001GB
test 0.000GB
world 0.000GB
dba58:PRIMARY> use world
switched to db world
dba58:PRIMARY> db.dropDatabase()
..............
dba58:PRIMARY> show dbs
admin 0.000GB
config 0.000GB
local 0.001GB
test 0.000GB
[mongo@db01 ~]$ mongorestore --port 28017 -d world1 /data/backup/world/
恢復之前先刪掉
[mongo@db01 ~]$ mongorestore --port 28017 -d world1 /data/backup/world/ --drop

mongodump和mongorestore高級企業應用(–oplog)

注意:這是replica set 或者master/slave 模式專用
1.oplog 介紹
在replica set 中oplog 是一個定容集合(capped collection),它的默認大小是磁盤空間的5%(可以
通過--oplogSizeMB 參數修改).
位於local 庫的db.oplog.rs,有興趣可以看看裏面到底有些什麼內容。
其中記錄的是整個mongodb 實例一段時間內數據庫的所有變更(插入/更新/刪除)操作。
當空間用完時新記錄自動覆蓋最老的記錄。
其覆蓋範圍被稱作oplog 時間窗口。需要注意的是,因爲oplog 是一個定容集合,
所以時間窗口能覆蓋的範圍會因爲你單位時間內的更新次數不同而變化。
想要查看當前的oplog 時間窗口預計值,可以使用以下命令:
dba58:PRIMARY> use local
dba58:PRIMARY> db.oplog.rs.find().pretty()
..................................
"ts" : Timestamp(1562403898, 1),
"op" : "n"
"o" :
"i": insert
"u": update
"d": delete
"c": db cmd
..................................
dba58:PRIMARY> rs.printReplicationInfo()
configured oplog size: 1024MB #集合大小
log length start to end: 104539secs (29.04hrs) #預計窗口覆蓋時間
oplog first event time: Sat Jul 06 2019 17:02:15 GMT+0800 (CST)
oplog last event time: Sun Jul 07 2019 22:04:34 GMT+0800 (CST)
now: Sun Jul 07 2019 22:04:38 GMT+0800 (CST)
2. oplog 企業級應用
(1)實現熱備,在備份時使用--oplog 選項
注:爲了演示效果我們在備份過程,模擬數據插入
(2)準備測試數據
[mongo@db01 ~]$ mongo db01:28017
dba58:PRIMARY> use oldboy
switched to db oldboy
dba58:PRIMARY> for(var i = 1 ;i < 100; i++) {
db.foo.insert({a:i});
}
dba58:PRIMARY> use local
dba58:PRIMARY> db.oplog.rs.find({"op":"i"}).pretty()
(3) oplog 配合mongodump 實現熱備
作用介紹:--oplog 會記錄備份過程中的數據變化。會以oplog.bson 保存下來
[mongo@db01 ~]$ mongodump --port 28017 --oplog -o /data/backup
恢復
[mongo@db01 ~]$ mongorestore --port 28017 --oplogReplay /data/backup --drop

oplog高級應用

背景:每天0 點全備,oplog 恢復窗口爲48 小時
某天,上午10 點world.city 業務表被誤刪除。
恢復思路:
0、停應用
2、找測試庫
3、恢復昨天晚上全備
4、截取全備之後到world.city 誤刪除時間點的oplog,並恢復到測試庫
5、將誤刪除表導出,恢復到生產庫
恢復步驟:
模擬故障環境:
1、全備數據庫
模擬原始數據
[mongo@db01 ~]$ mongo db01:28017
dba58:PRIMARY> use wo
dba58:PRIMARY> for(var i = 1 ;i < 20; i++) {
db.ci.insert({a: i});
}
2.全備
[mongo@db01 ~]$ rm -rf /data/backup/*
[mongo@db01 ~]$ mongodump --port 28017 --oplog -o /data/backup
--oplog 功能:在備份同時,將備份過程中產生的日誌進行備份
文件必須存放在/data/backup 下,自動命令爲oplog.bson
3.再次模擬數據
[mongo@db01 ~]$ mongo db01:28017
dba58:PRIMARY> use wo
dba58:PRIMARY> db.ci1.insert({id:1})
dba58:PRIMARY> db.ci2.insert({id:2})
dba58:PRIMARY> show tables
ci
ci1
ci2
4.上午10 點:刪除wo 庫下的ci 表
10:00 時刻,誤刪除
dba58:PRIMARY> db.ci.drop()
true
dba58:PRIMARY> show tables
ci1
ci2
5.備份現有的oplog.rs 表
[mongo@db01 ~]$ mongodump --port 28017 -d local -c oplog.rs -o /data/backup
6.截取oplog 並恢復到drop 之前的位置
更合理的方法:登陸到原數據庫
[mongo@db01 ~]$ mongo db01:28017
dba58:PRIMARY> use local
dba58:PRIMARY> db.oplog.rs.find({ns:"wo.$cmd"}).pretty();
{
"ts" : Timestamp(1562510676, 1),
"t" : NumberLong(20),
"h" : NumberLong("-6833353909054714034"),
"v" : 2,
"op" : "c",
"ns" : "wo.$cmd",
"ui" : UUID("327876dd-5032-4914-a080-58707e0cd867"),
"wall" : ISODate("2019-07-07T14:44:36.031Z"),
"o" : {
"drop" : "ci"
}
}
7.恢復備份+應用oplog
[mongo@db01 ~]$ cd /data/backup/local/
[mongo@db01 /data/backup/local]$ ls
oplog.rs.bson oplog.rs.metadata.json
[mongo@db01 /data/backup/local]$ cp oplog.rs.bson ../oplog.bson
[mongo@db01 /data/backup/local]$ rm -rf /data/backup/local/
[mongo@db01 ~]$ mongorestore --port 28017 --oplogReplay --oplogLimit "1562510676:1" --drop
/data/backup/
[mongo@db01 ~]$ mongo db01:28017
dba58:PRIMARY> use wo
switched to db wo
dba58:PRIMARY> show tables
ci
ci1
ci2

升級步驟

1.首先確保是副本集狀態
2.先關閉1 個副本節點
3.檢測數據是否可以升級
4.升級副本節點的可執行文件
5.更新配置文件
6.啓動升級後的副本節點
7.確保集羣工作正常
8.滾動升級其他副本節點
9.最後主節點降級
10.確保集羣 可用
11.關閉降級的老的主節點
12.升級老的主節點
13.重新加入集羣

口爲48 小時
某天,上午10 點world.city 業務表被誤刪除。
恢復思路:
0、停應用
2、找測試庫
3、恢復昨天晚上全備
4、截取全備之後到world.city 誤刪除時間點的oplog,並恢復到測試庫
5、將誤刪除表導出,恢復到生產庫
恢復步驟:
模擬故障環境:
1、全備數據庫
模擬原始數據
[mongo@db01 ~]$ mongo db01:28017
dba58:PRIMARY> use wo
dba58:PRIMARY> for(var i = 1 ;i < 20; i++) {
db.ci.insert({a: i});
}
2.全備
[mongo@db01 ~]$ rm -rf /data/backup/*
[mongo@db01 ~]$ mongodump --port 28017 --oplog -o /data/backup
–oplog 功能:在備份同時,將備份過程中產生的日誌進行備份
文件必須存放在/data/backup 下,自動命令爲oplog.bson
3.再次模擬數據
[mongo@db01 ~]$ mongo db01:28017
dba58:PRIMARY> use wo
dba58:PRIMARY> db.ci1.insert({id:1})
dba58:PRIMARY> db.ci2.insert({id:2})
dba58:PRIMARY> show tables
ci
ci1
ci2
4.上午10 點:刪除wo 庫下的ci 表
10:00 時刻,誤刪除
dba58:PRIMARY> db.ci.drop()
true
dba58:PRIMARY> show tables
ci1
ci2
5.備份現有的oplog.rs 表
[mongo@db01 ~]$ mongodump --port 28017 -d local -c oplog.rs -o /data/backup
6.截取oplog 並恢復到drop 之前的位置
更合理的方法:登陸到原數據庫
[mongo@db01 ~]$ mongo db01:28017
dba58:PRIMARY> use local
dba58:PRIMARY> db.oplog.rs.find({ns:“wo.KaTeX parse error: Expected 'EOF', got '}' at position 5: cmd"}̲).pretty(); { "…cmd”,
“ui” : UUID(“327876dd-5032-4914-a080-58707e0cd867”),
“wall” : ISODate(“2019-07-07T14:44:36.031Z”),
“o” : {
“drop” : “ci”
}
}
7.恢復備份+應用oplog
[mongo@db01 ~]$ cd /data/backup/local/
[mongo@db01 /data/backup/local]$ ls
oplog.rs.bson oplog.rs.metadata.json
[mongo@db01 /data/backup/local]$ cp oplog.rs.bson …/oplog.bson
[mongo@db01 /data/backup/local]$ rm -rf /data/backup/local/
[mongo@db01 ~]$ mongorestore --port 28017 --oplogReplay --oplogLimit “1562510676:1” --drop
/data/backup/
[mongo@db01 ~]$ mongo db01:28017
dba58:PRIMARY> use wo
switched to db wo
dba58:PRIMARY> show tables
ci
ci1
ci2


# 升級步驟

1.首先確保是副本集狀態
2.先關閉1 個副本節點
3.檢測數據是否可以升級
4.升級副本節點的可執行文件
5.更新配置文件
6.啓動升級後的副本節點
7.確保集羣工作正常
8.滾動升級其他副本節點
9.最後主節點降級
10.確保集羣 可用
11.關閉降級的老的主節點
12.升級老的主節點
13.重新加入集羣


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章