mongodb備份每一天的數據

需求:把mongodb裏面存儲6個月的數據備份到本地,一每天的來備份,方便對備份管理。而後mongo保留一週的數據(優化查詢速度,能夠用mongo的ttl來實現,可是個人業務場景不太適合用ttl索引)。而後crontab備份天天的數據,控制備份的數據只在6個月的範圍以內。

第一步:先把mongo裏面6個月的數據一每天的備份出來(人工操做會累死,寫個腳本)

import os
from datetime import datetime, timedeltamongodb

username = '帳號'
password = '密碼'
nowDate = datetime.today().date()
lastDate = nowDate - timedelta(days=185)數據庫

while nowDate != lastDate:
startDate, endDate = lastDate, lastDate + timedelta(days=1)
dirName = startDate.strftime("%Y-%m-%d")bash

startDate = startDate.strftime("%Y-%m-%d %H:%M:%S")
endDate = endDate.strftime("%Y-%m-%d %H:%M:%S")性能

lastDate += timedelta(days=1)
command = 'mongodump -d pusher -c records -q \'{\"$and\":[{\"create_time\":{\"$lt\":"%s"}},{\"create_time\":{\"$gt\":"%s"}}]}\' ' \
'--gzip --archive=/home/deploy/mongobackup/"%s".archive -u "%s" -p "%s"' %(endDate, startDate, dirName, username, password)測試

os.system(command)優化

備份完以後你的目錄下面應該是這樣子的spa

 

能夠用如下命令來測試下,測試圖我不上了3d

(1)先登陸mongo, 在use相應的數據庫rest

mongo --port 27017 -u "" -p "" --authenticationDatabase ""
use "your db"

(2)查詢某一天的數據code

db.dbname.find({"$and":[{"create_time":{"$gt":"2019-01-21 00:00:00"}},{"create_time":{"$lt":"2019-01-22 00:00:00"}}]})

或者直接統計:db.dbname.count({"$and":[{"create_time":{"$gt":"2019-01-21 00:00:00"}},{"create_time":{"$lt":"2019-01-22 00:00:00"}}]})

(3)刪除這一天的數據

db.dbname.remove({"$and":[{"create_time":{"$gt":"2019-01-21 00:00:00"}},{"create_time":{"$lt":"2019-01-22 00:00:00"}}]})

(4)恢復某一天的數據

mongorestore -u "" -p "" --authenticationDatabase dbname --nsInclude db.collection  --gzip --archive=2019-01-21/

# db.collection  --》 數據庫.表名
# 這裏使用了--gzip壓縮, 不壓縮文件太大了, 不過壓縮的話會消耗必定的性能,看我的須要

(5)測試一下數據有沒有恢復(重複第二步的命令)

db.dbname.find({"$and":[{"create_time":{"$gt":"2019-01-21 00:00:00"}},{"create_time":{"$lt":"2019-01-22 00:00:00"}}]})

或者直接統計:db.dbname.count({"$and":[{"create_time":{"$gt":"2019-01-21 00:00:00"}},{"create_time":{"$lt":"2019-01-22 00:00:00"}}]})

 

第二步:寫天天備份的腳本,第一步腳本通常只跑一次,這個腳本纔是用來維護的。

import os
from datetime import datetime, timedelta

username = ''
password = ''

endDate = datetime.today().date()
startDate = endDate - timedelta(days=1)
dirName = startDate.strftime("%Y-%m-%d")

startDate = startDate.strftime("%Y-%m-%d %H:%M:%S")
endDate = endDate.strftime("%Y-%m-%d %H:%M:%S")

command = 'mongodump -d db -c collection -q \'{\"$and\":[{\"create_time\":{\"$lt\":"%s"}},{\"create_time\":{\"$gt\":"%s"}}]}\'   ' \
          '-o  "%s" -u "%s" -p "%s"' %(endDate, startDate, dirName, username, password)

os.system(command)

 

第三步:確保備份數據的可用性以後,咱們就開始刪除mongo裏面的數據了,只保留最近一個星期的

 這一步能夠寫成腳本,contrab去天天執行

import os
from datetime import datetime, timedelta

username = ''
password = ''

queryDate = datetime.today().date() - timedelta(days=7)
queryDate = queryDate.strftime("%Y-%m-%d %H:%M:%S")

command = 'mongo dbname -u"%s" -p"%s" --eval \'db.records.remove({\"create_time\":{\"$lt\":"%s"}})\'' %(username, password, queryDate)

os.system(command)

 

總結:

1.先把第一個腳本運行一遍,生成每一天的備份文件。

2.把第二,第三個腳本整合在一塊兒,用contrab天天執行。(mongoBackupByday.py)

import os
from datetime import datetime, timedelta

username = ''
password = ''

# 1. 先備份前一天的數據

endDate = datetime.today().date()
startDate = endDate - timedelta(days=1)
dirName = startDate.strftime("%Y-%m-%d")

startDate = startDate.strftime("%Y-%m-%d %H:%M:%S")
endDate = endDate.strftime("%Y-%m-%d %H:%M:%S")

command = 'mongodump -d dbname -c collection -q \'{\"$and\":[{\"create_time\":{\"$lt\":"%s"}},{\"create_time\":{\"$gt\":"%s"}}]}\'   ' \
          '-o  "%s" -u "%s" -p "%s"' %(endDate, startDate, dirName, username, password)

os.system(command)


# 2. 在清理7天以前的數據
queryDate = datetime.today().date() - timedelta(days=7)
queryDate = queryDate.strftime("%Y-%m-%d %H:%M:%S")
command = 'mongo dbname -u"%s" -p"%s" --eval \'db.collection.remove({\"create_time\":{\"$lt\":"%s"}})\'' %(username, password, queryDate)

os.system(command)

設置crontab

crontab -e

 

還有一個任務就是,控制備份文件的數量,contrab job不斷備份,文件夾下面仍是隻保留6個月的備份文件

#!/bin/bash

# 定義要檢測的文件夾
BACK_DIR=/home/deploy/mongobackup

# 設置要保存的文件個數
SAVE_COUNT=185

cd $BACK_DIR

# 1.判斷文件個數
count=$(ls -l | grep "^-" | wc -l)

delcount=$[$count - $SAVE_COUNT]

# 2.是否進行刪除
if [ $delcount -gt 0 ];then
    # 獲取時間最久的文件名稱
    filename=$(ls -tr | head -n $delcount)
    for each in ${filename[*]}
    do
        rm -rf $each
        echo "deling file is" $each
    done
fi

 

也加到進去crontab 裏面,每週一次

 

但願這篇文章能夠幫助到有須要的朋友~

相關文章
相關標籤/搜索