2019年05月10日 16:44:08 zl1zl2zl3 閱讀數 11mysql
前段時間,我的小程序 IT牧場
因服務器磁盤空間被佔滿,致使MongoDB掛了。清理了一些無用的數據後,重啓MongoDB,居然沒法啓動,一番折騰(20分鐘)後,總算修復了。這讓我意識到:雖然是我的小項目,但也必須按期備份啊,不然數據丟了很尷尬的說。sql
碎碎念mongodb
•我不是MongoDB高手,之因此選擇MongoDB,是由於需求不明確——MongoDB很適合不明確需求場景的開發。•我的對Elasticsearch更熟悉,Elasticsearch也很適合不定需求的業務開發;但我的服務器只有1G內存,用Elasticsearch得升級服務器,得花好多錢啊啊啊。shell
MongoDB備份比較簡單,只需用內置的 mongodump
便可,命令格式以下:數據庫
mongodump -h {mongodb主機名}:{端口} -u {帳號} -p {密碼} -d {數據庫名稱} -o {存儲路徑}
然而,筆者爲MongoDB設置的密碼是帶有特殊字符的,例如 @#$\
之類,直接以如上形式執行命令,會報錯!小程序
因此筆者選擇不帶 -p 參數執行命令,即:服務器
mongodump -h {mongodb主機名}:{端口} -u {帳號} -d {數據庫名稱} -o {存儲路徑}
而後,命令提示符會提示輸入密碼。例如:ssh
# mongodump -h 127.0.0.1 -u user -d itmuch -o /tmp/somepathEnter password:
至此已實現MongoDB的備份。然而,手動備份仍是挺麻煩的,怎麼實現備份的自動化呢?工具
正常來講,自動備份是比較簡單的——只需將手動備份的命令作成Shell腳本,並設置定時任務便可。然而,筆者的場景,命令是須要交互式輸入密碼的啊!spa
怎麼才能自動輸入密碼呢?expect
登場了——一款提供自動交互的工具。
yum install -y 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的自動登陸等。腳本的套路都和本文展現的結構基本相似。