1. 程式人生 > >MongoDB自動備份全過程實錄

MongoDB自動備份全過程實錄

MongoDB自動備份全過程實錄

2019年05月10日 16:44:08 zl1zl2zl3 閱讀數 12

前段時間,個人小程式 IT牧場 因伺服器磁碟空間被佔滿,導致MongoDB掛了。清理了一些無用的資料後,重啟MongoDB,竟然無法啟動,一番折騰(20分鐘)後,總算修復了。這讓我意識到:雖然是個人小專案,但也必須定期備份啊,否則資料丟了很尷尬的說

碎碎念

•我不是MongoDB高手,之所以選擇MongoDB,是因為需求不明確——MongoDB很適合不明確需求場景的開發。•個人對Elasticsearch更熟悉,Elasticsearch也很適合不定需求的業務開發;但個人伺服器只有1G記憶體,用Elasticsearch得升級伺服器,得花好多錢啊啊啊。

MongoDB備份比較簡單,只需用內建的 mongodump 即可,命令格式如下:

mongodump -h {mongodb主機名}:{埠}  -u {賬號} -p {密碼} -d {資料庫名稱} -o {儲存路徑}

然而,筆者為MongoDB設定的密碼是帶有特殊字元的,例如 @#$\ 之類,直接以如上形式執行命令,會報錯

所以筆者選擇不帶 -p 引數執行命令,即:

mongodump -h {mongodb主機名}:{埠}  -u {賬號} -d {資料庫名稱} -o {儲存路徑}

然後,命令提示符會提示輸入密碼。例如:

# mongodump -h 127.0.0.1 -u user -d itmuch -o /tmp/somepathEnter password:

至此已實現MongoDB的備份。然而,手動備份還是挺麻煩的,怎麼實現備份的自動化呢?

自動備份

正常來說,自動備份是比較簡單的——只需將手動備份的命令做成Shell指令碼,並設定定時任務即可。然而,筆者的場景,命令是需要互動式輸入密碼的啊!

怎麼才能自動輸入密碼呢expect 登場了——一款提供自動互動的工具

安裝expect

yum install -y expect

編寫expect指令碼

expect語法非常簡單,和Shell幾乎一樣。筆者的指令碼編寫如下:

#!/bin/expect
# spawn是expect的語句,執行命令前需新增該字眼
set DATE [exec date "+%Y-%m-%d"]
set DIR /xxxxx/dbbak-$DATE
spawn rm -rf $DIR
spawn echo 'removing...$DIR'
spawn mongodump -h {host:port}  -u {user} -d {dbname} -o $DIR
# 互動獲取是否返回password:關鍵字
expect "password:"
# 將密碼傳送過去,注意最後的換行不能少,否則得人工輸入回車。
send "密碼\r"
# 停留在遠端控制檯,沒有這行就會直接返回本地控制檯,而不等shell執行完
interact

註釋很全面了,聰明的你閱讀肯定沒有壓力。最終備份出來的檔案會存放在 /xxxxx/dbbak-備份日期 目錄中。

自動備份

筆者利用Linux定時任務實現自動執行。

crontab -e

在新視窗中新增如下內容:

0 0 1 * * ? /usr/bin/expect 上面expect shell的完整路徑

原本以為這樣就可以定時執行了,然而卻無法正常執行

百度後,將指令碼修改為如下,終於可以正常執行了。

#!/bin/expect
# spawn是expect的語句,執行命令前需新增該字眼
set DATE [exec date "+%Y-%m-%d"]
set DIR /xxxxx/dbbak-$DATE
spawn rm -rf $DIR
spawn echo 'removing...$DIR'
spawn mongodump -h {host:port}  -u {user} -d {dbname} -o $DIR
# 互動獲取是否返回password:關鍵字
expect "password:"
# 將密碼傳送過去,注意最後的換行不能少,否則得人工輸入回車。
send "密碼\r"

set timeout 120
expect eof

exit

總結

本文沒什麼難點,都是一些細節——

•因為密碼含有特殊字元,所以需要互動式輸入密碼;•因為要互動式輸入密碼,所以使用了expect

寫出來主要是總結下踩到的坑,另外,expect是一款通用的提供自動互動的工具,用來實現ssh的自動登入、sftp的自動登入、mysql的自動登入等。指令碼的套路都和本文展示的