02 . MongoDB複製集,分片集,備份與恢復

youmen發表於2021-04-19

複製集

MongoDB複製集RS(ReplicationSet): 基本構成是1主2從的結構,自帶互相監控投票機制(Raft(MongoDB)Paxos(mysql MGR 用的是變種))

如果發生主庫當機, 複製集內部會進行投票選舉,選擇一個新的主庫替代原有主庫對外提供服務。同時複製集會自動通知。客戶端程式, 主庫已經發生切換了, 應用就會連線到新的主庫;

4.png

配置Replication Set

1 . 單臺配置多例項

// 多套目錄
su - mongod 
mkdir -p /mongodb/{28017,28018,28019,28020}/{conf,data,log,bin}

2 . 配置檔案

cat > /mongodb/28017/conf/mongod.conf <<EOF
systemLog:
  destination: file
  path: /mongodb/28017/log/mongodb.log
  logAppend: true
storage:
  journal:
    enabled: true
  dbPath: /mongodb/28017/data
  directoryPerDB: true
  #engine: wiredTiger
  wiredTiger: # 引擎功能有事務、行級鎖(4.0以後事務支援才完全)
    engineConfig:
      cacheSizeGB: 1  # 緩衝功能,緩衝區大小
      directoryForIndexes: true
    collectionConfig:
      blockCompressor: zlib
    indexConfig:
      prefixCompression: true
processManagement:
  fork: true
net:
  bindIp: 192.168.0.4,127.0.0.1
  port: 28017
replication: 							# 複製集相關的配置
  oplogSizeMB: 2048 			# 和二進位制相關的日誌,這裡設定兩個G
  replSetName: my_repl	  # 複製集的名
EOF

cp /mongodb/28017/conf/mongod.conf /mongodb/28018/conf/mongod.conf
cp /mongodb/28017/conf/mongod.conf /mongodb/28019/conf/mongod.conf
cp /mongodb/28017/conf/mongod.conf /mongodb/28020/conf/mongod.conf
sed -i 's#28017#28018#g' /mongodb/28018/conf/mongod.conf 
sed -i 's#28017#28019#g' /mongodb/28019/conf/mongod.conf
sed -i 's#28017#28020#g' /mongodb/28020/conf/mongod.conf

啟動多個例項

mongod -f /mongodb/28017/conf/mongod.conf
mongod -f /mongodb/28018/conf/mongod.conf
mongod -f /mongodb/28019/conf/mongod.conf
mongod -f /mongodb/28020/conf/mongod.conf

關閉多個示例

mongod -f /mongodb/28017/conf/mongod.conf --shutdown
mongod -f /mongodb/28018/conf/mongod.conf --shutdown
mongod -f /mongodb/28019/conf/mongod.conf --shutdown
mongod -f /mongodb/28020/conf/mongod.conf --shutdown

檢視4個埠是否啟動成功

netstat -lnp|grep 280

配置普通複製集

1主2從

mongo --port 28017 admin
// _id和配置檔案的replication.replSetName保持一致
config = {_id: 'my_repl', members: [
                          {_id: 0, host: '192.168.0.4:28017'},
                          {_id: 1, host: '192.168.0.4:28018'},
                          {_id: 2, host: '192.168.0.4:28019'}]
}

// 初始化
rs.initiate(config) 

// 查詢複製集狀態
rs.status();

配置1主1從1個arbiter

arbiter節點:主要負責選主過程中的投票,但是不儲存任何資料,也不提供任何服務

mongo --port 28017 admin
config = {_id: 'my_repl', members: [
                          {_id: 0, host: '10.9.119.18:28017'},
                          {_id: 1, host: '10.9.119.18:28018'},
                          {_id: 2, host: '10.9.119.18:28019',"arbiterOnly":true}]
          }    
		  
rs.initiate(config) 

rs.status();

新增arbiter節點

連線到主節點
>rs.status(); 檢視哪個是主節點"stateStr" : "PRIMARY"

mongo --port 28017 admin

新增仲裁節點
>rs.addArb("192.168.0.4:28020")

檢視節點狀態
>rs.isMaster()

        "hosts" : [
                "192.168.0.4:28017",
                "192.168.0.4:28018",
                "192.168.0.4:28019"
        ],
        "arbiters" : [
                "192.168.0.4:28020"
        ],

刪除節點和新增節點

rs.remove("192.168.0.4:28018"); // 刪除一個節點
rs.isMaster() // 檢視節點狀態
rs.add("192.168.0.4:28018")// 新增從節點
rs.isMaster() // 檢視節點狀態

特殊從節點

介紹:
** arbiter節點:主要負責選主過程中的投票,但是不儲存任何資料,也不提供任何服務
hidden節點:隱藏節點,不參與選主,也不對外提供服務。
delay節點: 延時節點,資料落後於主庫一段時間,因為資料是延時的,也不應該提供服務或參與選主,所以通常會配合hidden(隱藏), 一般用來解決邏輯損壞問題;**

**一般情況下會將delay+hidden一起配置使用**

配置延時節點(一般延時節點也配置成hidden)

cfg=rs.conf() 
cfg.members[2].priority=0 		//這個[2]是什麼意思,從rs.conf()的"members"開始數(從0開始),跟id沒關係
cfg.members[2].hidden=true		// 隱藏起來,不參與業務
cfg.members[2].slaveDelay=120 // 延時從庫
rs.reconfig(cfg)    

>rs.conf(); 如以下的"_id" : 3 就是[2]
{
        "_id" : "my_repl",
        "version" : 4,
        "protocolVersion" : NumberLong(1),
        "members" : [
        		{
                        "_id" : 0,
                        "host" : "192.168.0.4:28017",
                        "arbiterOnly" : false,
                        "buildIndexes" : true,
                        "hidden" : false,
                        "priority" : 1,
                        "tags" : {

                        },
                        "slaveDelay" : NumberLong(0),
                        "votes" : 1
                },
                {
                        "_id" : 1,
                        "host" : "192.168.0.4:28018",
                        "arbiterOnly" : false,
                        "buildIndexes" : true,
                        "hidden" : false,
                        "priority" : 1,
                        "tags" : {

                        },
                        "slaveDelay" : NumberLong(0),
                        "votes" : 1
                },
                {
                        "_id" : 3,
                        "host" : "192.168.0.4:28020",
                        "arbiterOnly" : true,
                        "buildIndexes" : true,
                        "hidden" : false,
                        "priority" : 0,
                        "tags" : {

                        },
                        "slaveDelay" : NumberLong(0),
                        "votes" : 1
                },
 ...
配置延時節點前
                {
                        "_id" : 3,
                        "host" : "192.168.0.4:28020",
                        "arbiterOnly" : true,
                        "buildIndexes" : true,
                        "hidden" : false,
                        "priority" : 0,
                        "tags" : {

                        },
                        "slaveDelay" : NumberLong(0),
                        "votes" : 1
                },
-----------------------------------------------------------------
配置延時節點後
				{
                        "_id" : 3,
                        "host" : "192.168.0.4:28020",
                        "arbiterOnly" : true,
                        "buildIndexes" : true,
                        "hidden" : true,
                        "priority" : 0,
                        "tags" : {

                        },
                        "slaveDelay" : NumberLong(120),
                        "votes" : 1
                },

取消延時節點配置

cfg=rs.conf() 
cfg.members[2].priority=1
cfg.members[2].hidden=false
cfg.members[2].slaveDelay=0
rs.reconfig(cfg)
rs.conf()檢視取消配置後
                {
                        "_id" : 3,
                        "host" : "192.168.0.4:28020",
                        "arbiterOnly" : true,
                        "buildIndexes" : true,
                        "hidden" : false,
                        "priority" : 0,
                        "tags" : {

                        },
                        "slaveDelay" : NumberLong(0),
                        "votes" : 1
                },

分片叢集

分片叢集原理

MongoDB Sharding Cluster 分片叢集

分片是一種用於在多臺計算機之間分配資料的方法; MongoDB使用分片來支援具有非常大的資料集和高吞吐量操作的部署;

具有大資料集或高吞吐量應用程式的資料庫系統可能會挑戰單個伺服器的容量;
例如,高查詢率可能會耗盡伺服器的CPU容量;
大於系統RAM的工作集大小會增加磁碟驅動器的I/O容量;

解決系統增長的方法有兩種:垂直縮放和水平縮放;

垂直擴充套件

​ 涉及增加單個伺服器的容量,例如使用功能更強大的CPU,新增更多RAM或增加儲存空間量, 可用技術的侷限性可能會限制一臺計算機對於給定的工作負載沒有足夠的功能, 此外, 基於雲的提供程式具有基於可用硬體配置的嚴格上限, 結果, 對於垂直縮放有實際的最大值;

水平擴充套件
涉及劃分系統資料集並在多臺伺服器上載入, 並新增其他伺服器以根據需要增加容量, 雖然單臺計算機的整體速度或容量可能不高,但是每臺計算機只能處理全部工作量的一部分,因此與單臺高速大容量伺服器相比, 可能會提供更高的效率, 擴充套件部署的容量僅需要根據需要新增其他伺服器, 這可以比單臺機器的高階硬體降低總體成本, 折衷方案是增加基礎結構和部署維護的複雜性;

MongoDB通過分片(sharding)支援水平擴充套件

MongoDB分片叢集由以下元件組成:

shard: 每個碎片包含碎片資料的子集; 每個分片都可以部署為[副本集(replica-set);
mongos: **mongos**充當查詢路由器, 在客戶端應用程式和分片群集之間提供介面;
config-servers: 配置伺服器儲存叢集的後設資料和配置設定, 從MongoDB 3.4開始,配置伺服器必須部署為副本集(CSRS);

分片叢集中元件的互動:
3.png

如何儲存的

mongo的自動分片就是靠Chunk遷移,拆分實現;

2.png

均衡特性

chunk分裂及遷移

隨著資料增長,其中的資料大小超過了配置的chunk size, 預設是64M, 則這個chunk就會分裂成兩個, 資料的增長會讓chunk分裂的越來越多, 這時候, 各個shard上的chunk數量就會不平衡, 這時,mongos中的一個元件balancer就會執行自動平衡, 把chunk從chunk數量最多的shard節點挪到最少的節點;

1.png

分片鍵shard key

必須為分片 collection 定義分片鍵
基於一個或多個列( 類似一個索引)
分片鍵定義資料空間;
想象key space 類似一條線上一個點資料
一個key range是一條線上一段資料;
我們可以按照分片鍵進行Range和Hash分片;

分片注意事項

分片鍵是不可變
分片鍵必須有索引
分片鍵大小限制512bytes
分片鍵用於路由查詢
Mongo不接受已進行collection級分片的collection上插入無分片鍵的文件(也不支援空值插入)

配置分片叢集

機器規劃

10個例項:38017-38026
	mongos:38017
	config-servers:			3臺構成的複製集(1主兩從,不支援arbiter)38018-38020(複製集名字configsvr)
	shard:
                sh1:38021-28023    (1主兩從,其中一個節點為arbiter,複製集名字sh1)
                sh2:38024-38026    (1主兩從,其中一個節點為arbiter,複製集名字sh2)

shard複製集配置

// 建立目錄
mkdir -p /mongodb/{38021,38022,38023,38024,38025,38026}/{conf,data,log}

// 配置檔案
---------------------------sh1---------------------------
cat > /mongodb/38021/conf/mongodb.conf<<EOF 
systemLog:
  destination: file
  path: /mongodb/38021/log/mongodb.log   
  logAppend: true
storage:
  journal:
    enabled: true
  dbPath: /mongodb/38021/data
  directoryPerDB: true
  #engine: wiredTiger
  wiredTiger:
    engineConfig:
      cacheSizeGB: 1
      directoryForIndexes: true
    collectionConfig:
      blockCompressor: zlib
    indexConfig:
      prefixCompression: true
net:
  bindIp: 0.0.0.0
  port: 38021
replication:
  oplogSizeMB: 2048
  replSetName: sh1
sharding:
  clusterRole: shardsvr
processManagement: 
  fork: true
EOF

cp  /mongodb/38021/conf/mongodb.conf  /mongodb/38022/conf/
cp  /mongodb/38021/conf/mongodb.conf  /mongodb/38023/conf/
sed -i 's#38021#38022#g' /mongodb/38022/conf/mongodb.conf 
sed -i 's#38021#38023#g' /mongodb/38023/conf/mongodb.conf 

---------------------------sh2---------------------------
cat > /mongodb/38024/conf/mongodb.conf<<EOF 
systemLog:
  destination: file
  path: /mongodb/38024/log/mongodb.log   
  logAppend: true
storage:
  journal:
    enabled: true
  dbPath: /mongodb/38024/data
  directoryPerDB: true
  wiredTiger:
    engineConfig:
      cacheSizeGB: 1
      directoryForIndexes: true
    collectionConfig:
      blockCompressor: zlib
    indexConfig:
      prefixCompression: true
net:
  bindIp: 0.0.0.0
  port: 38024
replication:
  oplogSizeMB: 2048
  replSetName: sh2
sharding:
  clusterRole: shardsvr
processManagement: 
  fork: true
EOF

cp  /mongodb/38024/conf/mongodb.conf  /mongodb/38025/conf/
cp  /mongodb/38024/conf/mongodb.conf  /mongodb/38026/conf/
sed -i 's#38024#38025#g' /mongodb/38025/conf/mongodb.conf 
sed -i 's#38024#38026#g' /mongodb/38026/conf/mongodb.conf 

啟動所有節點
mongod -f  /mongodb/38021/conf/mongodb.conf 
mongod -f  /mongodb/38022/conf/mongodb.conf 
mongod -f  /mongodb/38023/conf/mongodb.conf 
mongod -f  /mongodb/38024/conf/mongodb.conf 
mongod -f  /mongodb/38025/conf/mongodb.conf 
mongod -f  /mongodb/38026/conf/mongodb.conf 

搭建複製集
---------------------------sh1---------------------------
mongo --port 38021 admin

config = {_id: 'sh1', members: [
                          {_id: 0, host: '192.168.0.5:38021'},
                          {_id: 1, host: '192.168.0.5:38022'},
                          {_id: 2, host: '192.168.0.5:38023',"arbiterOnly":true}]
           }

rs.initiate(config)
---------------------------sh2---------------------------
mongo --port 38024  admin

config = {_id: 'sh2', members: [
                          {_id: 0, host: '192.168.0.5:38024'},
                          {_id: 1, host: '192.168.0.5:38025'},
                          {_id: 2, host: '192.168.0.5:38026',"arbiterOnly":true}]
           }
  
rs.initiate(config)

config-servers節點配置

** config-servers可以是一個節點,官方建議複製集。config-servers不能有arbiter;
mongodb 3.4之後,雖然要求config-servers為replica set,但是不支援arbiter;**

# 建立目錄
mkdir -p /mongodb/{38018,38019,38020}/{conf,data,log}
 
# 配置檔案
cat > /mongodb/38018/conf/mongodb.conf <<EOF
systemLog:
  destination: file
  path: /mongodb/38018/log/mongodb.conf
  logAppend: true
storage:
  journal:
    enabled: true
  dbPath: /mongodb/38018/data
  directoryPerDB: true
  #engine: wiredTiger
  wiredTiger:
    engineConfig:
      cacheSizeGB: 1
      directoryForIndexes: true
    collectionConfig:
      blockCompressor: zlib
    indexConfig:
      prefixCompression: true
net:
  bindIp: 0.0.0.0
  port: 38018
replication:
  oplogSizeMB: 2048
  replSetName: configReplSet
sharding:
  clusterRole: configsvr
processManagement: 
  fork: true
EOF

cp /mongodb/38018/conf/mongodb.conf /mongodb/38019/conf/
cp /mongodb/38018/conf/mongodb.conf /mongodb/38020/conf/
sed -i 's#38018#38019#g' /mongodb/38019/conf/mongodb.conf 
sed -i 's#38018#38020#g' /mongodb/38020/conf/mongodb.conf

# 啟動所有節點
mongod -f /mongodb/38018/conf/mongodb.conf 
mongod -f /mongodb/38019/conf/mongodb.conf 
mongod -f /mongodb/38020/conf/mongodb.conf

# 配置複製集
mongo --port 38018 admin

config = {_id: 'configReplSet', members: [
                          {_id: 0, host: '192.168.0.5:38018'},
                          {_id: 1, host: '192.168.0.5:38019'},
                          {_id: 2, host: '192.168.0.5:38020'}]
           }
rs.initiate(config)

mongos節點配置

# 建立目錄
mkdir -p /mongodb/38017/{conf,log}

# 配置檔案
cat >/mongodb/38017/conf/mongos.conf<<EOF
systemLog:
  destination: file
  path: /mongodb/38017/log/mongos.log
  logAppend: true
net:
  bindIp: 0.0.0.0
  port: 38017
sharding:
  configDB: configReplSet/192.168.0.5:38018,192.168.0.5:38019,192.168.0.5:38020
processManagement: 
  fork: true
EOF

# 啟動mongos
mongos -f /mongodb/38017/conf/mongos.conf

# 連線到其中一個mongos的admin庫
mongo --port 38017 admin

# 新增分片
db.runCommand( { addshard : "sh1/192.168.0.5:38021,192.168.0.5:38022,192.168.0.5:38023",name:"shard1"} )
db.runCommand( { addshard : "sh2/192.168.0.5:38024,192.168.0.5:38025,192.168.0.5:38026",name:"shard2"} )

# 列出分片
db.runCommand( { listshards : 1 } )

# 分片叢集整體狀態檢視
sh.status();

分片策略

RANGE分片配置及測試

Ranged根據分片鍵值將資料劃分為多個範圍。然後,根據分片鍵值為每個分配一個範圍
test庫下的vast大表進行手工分片

# 啟用資料庫分片功能
mongo --port 38017 admin

db.runCommand( { enablesharding : "test" } )	// ( { enablesharding : "資料庫名稱" } )

# 指定分片建對集合分片,建立索引
use test
>db.vast.ensureIndex( { id: 1 } )

# 開啟分片
use admin
>db.runCommand( { shardcollection : "test.vast",key : {id: 1} } )

# 集合分片驗證
use test
>for(i=1;i<1000000;i++){ db.vast.insert({"id":i,"name":"ruan","age":23,"date":new Date()}); }
>db.vast.stats()

# 分片結果測試
連線sh1
mongo --port 38021
db.vast.count();

# 連線sh2
mongo --port 38024
db.vast.count();

雜湊分片

雜湊分片涉及計算分片鍵欄位值的雜湊值。然後,根據雜湊的分片鍵值為每個分配一個範圍;
注意:使用雜湊索引解析查詢時,MongoDB自動計算雜湊值。應用程式也不會需要計算雜湊值;
對app庫下的vast大表進行hash;

# 連線到其中一個mongos
mongo --port 38017 admin

# 開啟資料庫分片功能
db.runCommand( { enablesharding : "app" } )

# 對app庫下的vast表建立hash索引
use app
db.vast.ensureIndex( { id: "hashed" } )

# 開啟分片
use admin
sh.shardCollection( "app.vast", { id: "hashed" } )

# 集合分片驗證
use app
for(i=1;i<100000;i++){ db.vast.insert({"id":i,"name":"ruan","age":23,"date":new Date()}); }

# hash分片結果測試
# 連線sh1
mongo --port 38021
use app 
db.vast.count();

# 連線sh2
mongo --port 38024
use app
db.vast.count();

分片操作

use admin
db.runCommand({ isdbgrid : 1})			# 判斷是否Shard叢集
db.runCommand({ listshards : 1})		# 列出所有分片資訊
db.printShardingStatus()						# 檢視分片的詳細資訊

# 列出開啟分片的資料庫
use config
db.databases.find( { "partitioned": true } )  # 或者 db.databases.find() //列出所有資料庫分片情況
db.collections.find().pretty()			# 檢視分片的片鍵

# 刪除分片節點(謹慎)
sh.getBalancerState()	確認blance是否在工作
db.runCommand( { removeShard: "shard2" } )	# 刪除shard2節點(謹慎)

# 刪除操作一定會立即觸發blancer!!!

balancer操作

mongos的一個重要功能,自動巡查所有shard節點上的chunk的情況,自動做chunk遷移;

什麼時候工作?
** 1 . 自動執行,會檢測系統不繁忙的時候做遷移;
2 . 在做節點刪除的時候,立即開始遷移工作(生產刪除節點千萬避免業務高峰期) ;
3 . balancer只能在預設定的時間視窗內執行;**

關閉和開啟blancer(備份的時候)

mongos> sh.stopBalancer()
mongos> sh.startBalancer()

預設定的時間做balancer

連線到其中一個mongos
mongo --port 38017 admin

use config	
sh.setBalancerState( true )
// 每天3-5點
db.settings.update({ _id : "balancer" }, { $set : { activeWindow : { start : "3:00", stop : "5:00" } } }, true )

sh.getBalancerWindow()	// 檢視balancer時間視窗
sh.status()

關於集合的balancer

關閉某個集合的balance

sh.disableBalancing("test.vast")

開啟某個集合的balancer

sh.enableBalancing("test.vast")

確定某個集合的balance是開啟或者關閉

db.getSiblingDB("config").collections.findOne({_id : "test.vast"}).noBalance;

備份與恢復

備份工具

mongoexport/mongoimport  匯入/匯出的是JSON格式或者CSV格式
mongodump/mongorestore   匯入/匯出的是BSON格式

JSON可讀性強但體積較大,BSON則是二進位制檔案,體積小但對人類幾乎沒有可讀性

版本相容性問題

在一些mongodb版本之間,BSON格式可能會隨版本不同而有所不同,所以不同版本之間用mongodump/mongorestore可能不會成功,具體要看版本之間的相容性。當無法使用BSON進行跨版本的資料遷移的時候,使用JSON格式即mongoexport/mongoimport是一個可選項。

跨版本的mongodump/mongorestore個人並不推薦,實在要做請先檢查文件看兩個版本是否相容(大部分時候是不相容的)

注意
JSON雖然具有較好的跨版本通用性,但其只保留了資料部分,不保留索引,賬戶等其他基礎資訊。使用時應該注意;

應用場景

mongoexport/mongoimport
匯入匯出可以是json/csv
1 . 異構平臺遷移  mysql  <---> mongodb
2 . 同平臺, 跨大版本:mongodb 2   <---> mongodb 3

mongodump/mongorestore
匯入匯出的是BSON格式,日常備份恢復時使用, 不同版本的BSON是不一樣的, 不能通用的;

匯出工具mongoexport

Mongodb中的mongoexport工具可以把一個collection匯出成JSON格式或CSV格式的檔案。
可以通過引數指定匯出的資料項,也可以根據指定的條件匯出資料。
1 . 版本差異較大

** 2 . 異構平臺資料遷移**

引數說明

mongoexport --help  
# 引數說明:
  -h:指明資料庫宿主機的IP
  -u:指明資料庫的使用者名稱
  -p:指明資料庫的密碼
  -d:指明資料庫的名字
  -c:指明collection的名字
  -f:指明要匯出那些列
  -o:指明到要匯出的檔名
  -q:指明匯出資料的過濾條件
  --authenticationDatabase admin

單表備份至json格式

備份檔案的名字可以自定義,預設匯出了JSON格式的資料

mongoexport  -h 127.0.0.1:27017 -uyoumen -pyoumen --authenticationDatabase admin -d app -c app -o /mongodb/bak/app.json

單表備份至csv格式

匯出CSV格式的資料,需要使用--type=csv引數

-f匯出的列頭

mongoexport  -h 127.0.0.1:27017  -uyoumen -pyoumen --authenticationDatabase admin -d app -c app --type=csv -f id  -o /mongodb/bak/app.csv

匯入工具mongoimport

Mongodb中的mongoimport工具可以把一個特定格式檔案中的內容匯入到指定的collection中。該工具可以匯入JSON格式資料,也可以匯入CSV格式資料;

引數說明

mongoimport --help
# 引數說明:
  -h:指明資料庫宿主機的IP
  -u:指明資料庫的使用者名稱
  -p:指明資料庫的密碼
  -d:指明資料庫的名字
  -c:指明collection的名字
  -f:指明要匯入那些列
  -j, //並行多少CPU

恢復json格式表資料

mongoimport  -h 127.0.0.1:27017  -uyoumen -pyoumen  --authenticationDatabase admin -d app -c app /mongodb/bak/app.json

// -j   並行匯入

恢復csv格式的檔案

# csv格式的檔案頭行,有列名字
mongoimport   -uroot -padmin --port 27017 --authenticationDatabase admin   -d app -c test2 --type=csv --headerline --file  /mongodb/bak/app.csv

# csv格式的檔案頭行,沒有列名字
mongoimport   -uroot -padmin --port 27017 --authenticationDatabase admin   -d app -c test3 --type=csv -f id --file  /mongodb/bak/app.csv

異構平臺遷移

mysql遷移mongodb

mysql開啟安全路徑
vim /etc/my.cnf   --->新增以下配置
secure-file-priv=/tmp

重啟資料庫生效
systemctl restart mysql

匯出mysql的表資料
select * from app.user into outfile '/tmp/user.csv' fields terminated by ',';
#fields terminated by ','    欄位間以,號分隔
#####其它引數
#optionally enclosed by '"'   欄位用"號括起
#escaped by '"'            欄位中使用的轉義符為"
#lines terminated by '\r\n';  行以\r\n結束

處理csv檔案
vim /tmp/user.csv   ----> 新增對應第一行列名資訊

mongodb中匯入csv檔案
mongoimport -uroot -padmin --port 27017 --authenticationDatabase admin -d app  -c user --type=csv --headerline --file  /tmp/user.csv

BSON工具介紹

mongodump能夠在Mongodb執行時進行備份,它的工作原理是對執行的Mongodb做查詢,然後將所有查到的文件寫入磁碟。但是存在的問題時使用mongodump產生的備份不一定是資料庫的實時快照,如果我們在備份時對資料庫進行了寫入操作,則備份出來的檔案可能不完全和Mongodb實時資料相等。另外在備份時可能會對其它客戶端效能產生不利的影響。

匯出工具mongodump

引數說明

mongodump --help
引數說明:
-h:指明資料庫宿主機的IP
-u:指明資料庫的使用者名稱
-p:指明資料庫的密碼
-d:指明資料庫的名字
-c:指明collection的名字
-o:指明到要匯出的檔名
-q:指明匯出資料的過濾條件
-j n 並行n個CPU
--oplog  備份的同時備份oplog

全庫備份

mongodump  -uroot -padmin --port 27017 --authenticationDatabase admin -o /mongodb/bak

備份單庫

mongodump   -uroot -padmin --port 27017 --authenticationDatabase admin -d app -o /mongodb/bak

備份庫下的集合

mongodump   -uroot -padmin --port 27017 --authenticationDatabase admin -d app -c test3 -o /mongodb/bak

壓縮備份

mongodump  -uroot -padmin --port 27017 --authenticationDatabase admin -o /mongodb/bak --gzip
mongodump  -uroot -padmin --port 27017 --authenticationDatabase admin -d app -o /mongodb/bak --gzip
mongodump  -uroot -padmin --port 27017 --authenticationDatabase admin -d app -c test3 -o /mongodb/bak --gzip

匯入工具mongorestore

引數說明

mongorestore --help
引數說明:
-h:指明資料庫宿主機的IP
-u:指明資料庫的使用者名稱
-p:指明資料庫的密碼
-d:指明資料庫的名字
-c:指明collection的名字
--drop表示恢復的時候把之前的集合drop掉(危險)
--oplogReplay 同時匯入oplog檔案

恢復全部

mongorestore -uroot -padmin --port 27017 --authenticationDatabase admin /mongodb/bak

恢復庫

mongorestore -uroot -padmin --port 27017 --authenticationDatabase admin -d app /mongodb/bak/app

恢復庫下的集合

mongorestore -uroot -padmin --port 27017 --authenticationDatabase admin -d app -c app  /mongodb/bak/app/app.bson.gz

--drop恢復

mongorestore   -uroot -padmin --port 27017 --authenticationDatabase admin -d app --drop /mongodb/bak/app

oplog介紹

mongodump和mongorestore對replica set或者master/slave使用

在replica set中oplog是一個定容集合(capped collection),它的預設大小是磁碟空間的5%(可以通過--oplogSizeMB引數修改)

oplog其中記錄的是整個mongod例項一段時間內資料庫的所有變更(插入/更新/刪除)操作。當空間用完時新記錄自動覆蓋最老的記錄。其覆蓋範圍被稱作oplog時間視窗。需要注意的是,因為oplog是一個定容集合,所以時間視窗能覆蓋的範圍會因為你單位時間內的更新次數不同而變化。

想要檢視當前的oplog時間視窗預計值,可以使用以下命令:

> rs.printReplicationInfo()
configured oplog size:   2048MB <--集合大小
log length start to end: 60295secs (16.75hrs) <--預計視窗覆蓋時間
oplog first event time:  Sat Apr 17 2021 00:26:26 GMT+0800 (CST)
oplog last event time:   Sat Apr 17 2021 17:11:21 GMT+0800 (CST)
now:                     Sat Apr 17 2021 17:11:29 GMT+0800 (CST)

檢視oplog的詳細資訊

use local 
db.oplog.rs.find().pretty()

oplog應用

實現熱備,在備份時使用--oplog選項,--oplog 會記錄備份過程中的資料變化,會以oplog.bson儲存下來

mongodump --port 28017 --oplog -o /mongodb/bak

ls /mongodb/bak/
admin  oplog.bson

恢復

mongorestore  --port 28017 --oplogReplay /mongodb/bak

oplog使用示例

背景:每天0點全備,oplog恢復視窗為48小時

某天,上午10點業務表被誤刪除。

恢復思路:

1、停應用

2、找測試庫

3、恢復昨天晚上全備

4、擷取全備之後到world.city誤刪除時間點的oplog,並恢復到測試庫

5、將誤刪除表匯出,恢復到生產庫

恢復步驟

備份現有的oplog.rs表
mongodump --port 28017 -d local -c oplog.rs  -o /mongodb/bak

擷取oplog並恢復到drop之前的位置
mongo --port 28017
use local
db.oplog.rs.find({op:"c"}).pretty();
-----------------
op的值說明:
    "i": insert
    "u": update
    "d": delete
    "c": db cmd
假設誤刪命令是db.test.drop() 這裡選”c“做關鍵查詢
-----------------
獲取到oplog誤刪除時間點位置
"ts" : Timestamp(1111111111, 1)  獲取時間這一關鍵段

恢復備份+oplog.bson
ls /mongodb/bak/local/
oplog.rs.bson  oplog.rs.metadata.json

cp /mongodb/bak/local/oplog.rs.bson /mongodb/bak/oplog.bson
rm -rf /mongodb/backup/local/
mongorestore --port 28018  --oplogReplay --oplogLimit "1111111111:1"  --drop   /mongodb/bak/
即可恢復誤刪的集合

分片叢集的備份思路

要備份什麼?

config server
shard 節點
---單獨進行備份

備份有什麼困難和問題?

(1)chunk遷移的問題
人為控制在備份的時候,避開遷移的時間視窗
(2)shard節點之間的資料不在同一時間點。
選業務量較少的時候

相關文章