一種既便捷又超便宜的數據庫(MySQL、MongoDB)備份與恢復方案:數據庫的備份和恢復是很古老的話題了,可是現有的方案沒找到順手的,沒辦法只能從新發明輪子了。代碼參考db-backup-and-restorehtml
詳細參見官網介紹:阿里雲的數據庫備份服務RBSpython
RBS知足需求場景中的一、二、3,功能仍是挺強大的,可是有兩個致命缺點,一個是貴,另外一個是死慢死慢的mysql
第一點:貴,RBS是按備份數據量收費的,而備份數據量以下所示,「經過備份鏈路的實際數據大小」,跟你每月執行備份的次數有關。若是我有50G數據,天天備份一次,每月就要1000多塊錢,另外備份存儲也要單獨收費 git
第二點:最不能忍受,恢復數據執行起來死慢死慢的,我作了個測試,總共50M數據文件,RBS恢復了2個小時尚未執行完,這麼點數據量用mongorestore,幾秒鐘就能夠執行完。github
總結: 不論是阿里雲的數據庫備份RBS仍是github已有的開源方案,都不是太適合咱們的業務場景需求,只好從新造輪子了。golang
【方案整體框架】包含兩個主要程序:sql
【基於時間衰減的備份存儲策略】 備份存儲的時間衰減策略: 越近的數據越重要,保存的時間間隔越小,份數越多;越老的數據重要性越小,保存的時間間隔越大,份數越少 能夠經過策略參數控制,例如:mongodb
"days": 6
, 最近6天,天天保存一份"weeks": 3
, 最近3周,每週保存一份"months": 6
, 最近6個月,每個月保存一份"years": 5
, 最近5年,每一年保存一份,超過5年以上就不保留備份了好比5年的歷史數據,備份數= 6 + 3 + 6 + 5 = 20docker
以每一個備份20G的存儲大小爲例,20G*20份==400G,購買一個500G的歸檔型存儲包,每一年的存儲費用爲135元,算是很是便宜的方案了(參加 阿里雲產品訂價-對象存儲OSS) 數據庫
【恢復程序】的執行邏輯以下面有限狀態機所示,用戶只須要根據引導輸入3個指令便可完成一個恢復:
python3.6版本以上
git clone https://github.com/perfectstorm88/db-backup-and-restore
cd db-backup-and-restore
pip install -r requirements.txt
cp config.sample.yml config.yml
複製代碼
最簡單的樣例以下:
tmpPath: './temp'
archivePath: './archive'
local:
retention: 10 # number of backups to keep locally
tasks:
- name: 'mongo_my_test1'
type: 'mongodb'
schedule: "day 13:15" # 天天 13:15執行
params: # 經過mongodump執行的參數
uri: "mongodb://test:test@127.0.0.1:13722/lcz_test1" #
複製代碼
有兩種啓動方式,啓動常駐進程,週期任務調度:
python backup.py -l
複製代碼
另外一種方式,是直接啓動任務,忽略schedule參數,當即執行數據庫備份,通常應用在測試場景,如
python backup.py -t mongo_my_test1
複製代碼
執行restore.py ,按着引導步驟執行便可
python restore.py
複製代碼
恢復程序】的執行邏輯以下面有限狀態機所示,用戶只須要根據引導輸入3個指令便可完成一個恢復:
執行 python restore.py
命令,過程以下:
*******************welcome to use database restore program****************
# 【輸入】選擇一個備份任務(任務名稱是在config.yml )
please choice the task to restore
0) mongo_lcz_test1
1) mysql_db1
-1) return last step
(choice task)->1
# 【輸入】選擇一個數據源文件
please choice the following file to restore
0) 20190829150621.zip 232.100 KB (local)
-1) return last step
(choice task)->0
# 【輸入】輸入目標數據庫的uri
please input the destination db uri,format is [scheme://][user[:[password]]@]host[:port][/schema][?attribute1=value1&attribute2=value2]
(such as mysql://root:123456@127.0.0.1/db1)
(uri)->mysql://root:123456@127.0.0.1/db2
# 檢查uri格式
now is check uri ....
# 解壓縮zip文件
unzip file:/root/db-backup-and-restore/./archive/mysql_db1/20190829150621.zip
# 執行數據庫恢復命令
2019-08-29 16:13:57,833 INFO start exec restore cmd: mysql -uroot -p123456 -h47.99.73.225 db2 < /root/db-backup-and-restore/temp/uIZ3XfhB/back.sql
2019-08-29 16:13:57,857 DEBUG mysql: [Warningder] Using a password on the command line interface can be insecure.
2019-08-29 16:14:01,041 DEBUG b
process exit
複製代碼
tmpPath: './temp'
archivePath: './archive'
# oss: # 存儲到OSS
# url: "http://oss-cn-hangzhou.aliyuncs.com"
# bucket: "jfjun4test"
# accessKey: "accessKey"
# secretKey: "secretKey"
# prefix: 'backup/' # oss中的存儲根路徑
# # 存儲策略,只有一個起做用,優先級timeDecay>retention>expireDays,
# expireDays: 730 # 最大保存天數
# retention: 14 # 最大保留分數
# timeDecay:
# - months: 6 # 若是超過2個月後,每月只保留一份
# - years: 10 # 若是超過2年後,每一年只保留一份
# - days: 6
# - weeks: 3
# 存放到本地,存放目錄 {archivePath}/{task.name}/
local:
# 稀疏策略,若是配置了稀疏策略,則retention失效,expireDays失效
expireDays: 730 # 最大保存天數
retention: 10 # 最大保留份數
timeDecay: # 時間衰減保存策略
days: 6, # 最近6天,天天保存一份
weeks: 3, # 最近3周,每週保存一份
months: 6, # 最近6個月,每個月保存一份
years: 5, # 最近5年,每一年保存一份,超過5年以上就不保留備份了
tasks:
- name: 'mongo_lcz_test1'
type: 'mongodb'
# schedule表示執行時間策略
# "day 03:21" # 天天 03:21執行
# "hour :31" # 每小時 31分執行
# "monday 03:21" # 每週一 03:21執行
schedule: "day 13:15" # 天天 13:15執行
params: # 經過mongodump執行的參數
# uri: "mongodb://test:test@127.0.0.1:13722/lcz_test1"
d: lcz_test1
u: test
p: test
h: 127.0.0.1:13722
- name: 'mysql_db1'
type: 'mysql'
schedule: "day :00" # 每週
params: # 經過mysqldumap執行的參數
# uri: "mysql://root:123456@127.0.0.1/db1"
u: "root"
p: "123456"
databases: "db1"
host: "127.0.0.1"
複製代碼
上述方案爲全量備份,比較適合於中小型業務場景,好比200G如下的的數據量,若是是過T的數據量,能夠考慮按期全量+增量備份方案,下面爲擴展閱讀