1 序言
相信大家都還記得這則新聞吧,歐洲雲端計算巨頭 OVH 位於法國斯特拉斯堡的機房發生嚴重火災,大火徹底摧毀了五層高、佔地 500 平方米的 SBG2 資料中心。
當地報紙稱 115 位消防員投入 6 個小時才將其撲滅。經過長達 6 個小時的持續燃燒,SBG2 內的資料恐怕已經徹底丟失。
大火對歐洲範圍內的眾多網站造成嚴重影響。據 Netcraft 稱,目前跨 464000 個域的多達 360 萬個網站皆已下線。
資料是無價的,所以生產環境中定時備份資料庫顯得尤為重要。備份能防止伺服器故障和人為誤操作帶來的資料丟失。
生產環境中linux作業系統也是伺服器的首選,所以我們今天就以linux為例,說一說資料庫備份。
具體以什麼資料庫為例呢,就以這幾年工作中接觸到的幾種常見資料庫為例吧。
- Oracle
- mysql
- postgresql
- mongoDB
在這裡呢也給自己挖一個坑,工作中呢也用到winserver 作為伺服器的情況,所以呢後面也整理更新下winserver 環境下資料庫備份。
2 crond 相關知識點
2.1 crond 是什麼?
- crond任務排程相當於我們日常生活中的鬧鐘。可以在某個時間點執行特定的命令和程式。
- linux系統自身定期執行的任務工作:例如輪詢系統日誌、備份系統資料、清理系統快取、防毒等等
- 使用者執行的工作任務:使用者透過設定任務排程,定時執行自己新增shell指令碼或簡單的指令。例如每隔1分鐘和網際網路上時間伺服器同步,每天凌晨1點備份資料庫等等
2.2 crontab 進行定時任務設定
2.2.1 crontab 指令選項說明
語法:
crontab[-e|-l|-r]
-e:編輯crontab 定時任務
-l:查詢crontab定時任務
-r:刪除當前使用者所有的crontab定時任務
2.2.2 crontab 指令使用格式
crontab使用者的定時任務一般分為6段(空格分隔,系統的定時任務則/etc/crontab分為7段),其中前五段位時間設定段,第六段為所要執行的命令或指令碼任務段。
①語法:
* * * * * cmd
①cmd為要執行的命令或指令碼,例如/server/scripts/lee.sh
②每個段之間必須要有空格。
② crontab語法格式中時間段的含義表
段 | 含義 | 取值範圍 |
---|---|---|
第一個“*” | 一小時當中的第幾分鐘 | 0-59 |
第二個“*” | 一天當中的第幾個小時 | 0-23 |
第三個“*” | 一個月當中的第幾天 | 1-31 |
第四個“*” | 一年當中的第幾個月 | 1-12 |
第五個“*” | 一週當中的星期幾 | 0-7(0和7都代表周天) |
③ crontab語法格式中特殊符號的含義表
特殊符號 | 含義 |
---|---|
* | "*" 表示任意時間都,就是“每”的意思,舉例:如00 01 * * * cmd 表示每月每週每日的凌晨1點執行cmd任務。 |
- | "-" 表示分隔符,表示一個時間範圍段,如17-19點,每小時的00分執行任務。00 17-19 * * * cmd 表示17,18,19點整點分別執行的意思。 |
, | "," 表示分隔時間段的意思。30 17,18,19 * * * cmd 表示每天17,18,19點的半點執行cmd 也可以和“-”結合使用,如: 30 3-5,17-19 * * * cmd 表示每天3、4、5和17、18、19 執行 |
/n | n代表數字 即”每隔n單位時間”,例如:每10分鐘執行一次任務可以寫 */10 * * * * cmd,其中 /10,的範圍是0-59,也可以寫成0-59/10 |
2.2.3 特定時間執行任務例子
① 30 23 * * * cmd 表示每天23:30分執行cmd命令
② 40 22 * * 1 cmd 表示每週一22:40分執行cmd命令
③ 30 0 1-12 * * cmd 表示每月1號和12號 00:30執行cmd命令
④ 30 0 * * 1-5 cmd 表示每週一和週五00:30執行命令
⑤ */10 4 * * * cmd 表示每天4:00每隔10分鐘執行一次cmd命令
2.2.4 crontab 設定步驟
這裡我們以每5分鐘同步一次網際網路時間為例進行說明
① 檢視crond服務是否啟動
/sbin/service crond status --檢視crond服務是否啟動
[root@xiezhr /]# /sbin/service crond status
Redirecting to /bin/systemctl status crond.service
● crond.service - Command Scheduler
Loaded: loaded (/usr/lib/systemd/system/crond.service; enabled; vendor preset: enabled)
Active: active (running) since Sun 2021-01-10 21:14:50 CST; 1 months 25 days ago
Main PID: 990 (crond)
CGroup: /system.slice/crond.service
└─990 /usr/sbin/crond -n
Jan 25 14:00:01 xiezhr crond[990]: /usr/sbin/sendmail: error while loading shared librari...ory
Jan 25 14:30:02 xiezhr crond[990]: /usr/sbin/sendmail: error while loading shared librari...ory
Jan 25 15:00:02 xiezhr crond[990]: /usr/sbin/sendmail: error while loading shared librari...ory
Jan 25 15:30:01 xiezhr crond[990]: /usr/sbin/sendmail: error while loading shared librari...ory
Jan 25 16:00:01 xiezhr crond[990]: /usr/sbin/sendmail: error while loading shared librari...ory
Jan 25 16:24:01 xiezhr crond[990]: (*system*) RELOAD (/etc/cron.d/yunjing)
Jan 28 11:18:01 xiezhr crond[990]: (*system*) RELOAD (/etc/cron.d/sgagenttask)
Jan 28 11:18:01 xiezhr crond[990]: (root) RELOAD (/var/spool/cron/root)
Feb 07 12:03:01 xiezhr crond[990]: (*system*) RELOAD (/etc/cron.d/yunjing)
Feb 07 12:03:01 xiezhr crond[990]: (root) RELOAD (/var/spool/cron/root)
Hint: Some lines were ellipsized, use -l to show in full.
如果crond服務沒啟動則執行如下命令啟動crond服務
/sbin/service crond start 啟動服務
檢視程式
[root@xiezhr /]# ps -ef|grep crond
root 990 1 0 Jan10 ? 00:00:22 /usr/sbin/crond -n
root 19552 15271 0 16:10 pts/1 00:00:00 grep --color=auto crond
② 編寫shell指令碼
在home路徑下新增如下shell指令碼
[root@xiezhr home]# vim /home/my.sh
/usr/sbin/ntpdate time.windows.com >/dev/null 2>&1
③ 給指令碼增加執行許可權
[root@xiezhr home]# chmod u+x /home/my.sh
④ 設定定時任務crontab
[root@xiezhr home]# crontab -e
*/5 * * * * /home/my.sh
3 各個資料庫備份指令碼
3.1 Oracle資料庫
#!/bin/bash
export ORACLE_HOME=/u01/app/oracle/product/11.2.0/db_1;
export ORACLE_SID=orcl;
export PATH=$ORACLE_HOME/bin:/usr/sbin:$PATH;
export LD_LIBRARY_PATH=$ORACLE_HOME/lib:/lib:/usr/lib;
export NLS_LANG=AMERICAN_AMERICA.ZHS16GBK
#以上程式碼為Oracle資料庫執行賬號oracle的系統環境變數設定,必須新增,否則crontab任務計劃不能執行。
date=date +%Y_%m_%d #獲取系統當前日期時間
days=7 #設定刪除7天之前的備份檔案
orsid=192.168.1.100:1521/orcl #Oracle資料庫伺服器IP、埠、SID
orowner=scott #備份此使用者下面的資料
bakuser=system #用此使用者來執行備份,必須要有備份操作的許可權
bakpass=oracle #執行備註的使用者密碼
bakdir=/backup/oracledata #備份檔案路徑,需要提前建立好
bakdata=$orowner"_"$date.dmp #備份資料庫名稱
baklog=$orowner"_"$date.log #備份執行時候生成的日誌檔名稱
ordatabak=$orowner"_"$date.tar.gz #最後儲存的Oracle資料庫備份檔案
cd $bakdir #進入備份目錄
mkdir -p $orowner #按需要備份的Oracle使用者建立目錄
cd $orowner #進入目錄
exp $bakuser/$bakpass@$orsid grants=y owner=$orowner file=$bakdir/$orowner/$bakdata log=$bakdir/$orowner/$baklog #執行備份
tar -zcvf $ordatabak $bakdata $baklog #壓縮備份檔案和日誌檔案
find $bakdir/$orowner -type f -name "*.log" -exec rm {} \; #刪除備份檔案
find $bakdir/$orowner -type f -name "*.dmp" -exec rm {} \; #刪除日誌檔案
find $bakdir/$orowner -type f -name "*.tar.gz" -mtime +$days -exec rm -rf {} \; #刪除7天前的備份(注意:{} \中間有空格)
以上exp備份,如果要採用expd備份,只需將上面執行語句換成下面的即可
expdp $bakuser/$bakpass@$orsid full=y cluster=n directory=$bakdir dumpfile=$bakdir/$orowner/$bakdata logfile=$bakdir/$orowner/$baklog
3.2 Mysql資料庫
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:/usr/local/mysql/bin
export PATH
dbuser='root' #資料庫使用者名稱
dbpasswd='123456' #資料庫密碼
dbname='test1 test2' #資料庫名,可以定義多個資料庫,中間以空格隔開,如 test1 test2
backtime=`date +%Y%m%d%H%M%S` #備份時間
logpath= '/home/mysql/backup' #日誌備份路徑
datapath='/home/mysql/backup' #資料備份路徑
echo "備份時間為${backtime},備份資料庫表 ${dbname} 開始" >> ${logpath}/mysqllog.log #日誌記錄頭部
#正式備份資料庫
for table in $dbname; do
source=`mysqldump -u ${dbuser} -p${dbpasswd} ${table}> ${logpath}/${backtime}.sql` 2>> ${logpath}/mysqllog.log;
#備份成功以下操作
if [ "$?" == 0 ];then
cd $datapath
tar jcf ${table}${backtime}.tar.bz2 ${backtime}.sql > /dev/null #為節約硬碟空間,將資料庫壓縮
rm -f ${datapath}/${backtime}.sql #刪除原始檔案,只留壓縮後檔案
cd $datapath
rm -rf `find . -name '*.sql.gz' -mtime +30` >> ${logpath}/mysqllog.log 2>&1 #刪除30天前備份檔案
echo "資料庫表 ${dbname} 備份成功!!" >> ${logpath}/mysqllog.log
else
echo “資料庫表 ${dbname} 備份失敗!!” >> ${logpath}/mysqllog.log #備份失敗則進行以下操作
fi
done
3.3 postgresql資料庫
#!/bin/bash
pg_user ='postgres'
export NLS_DATE_FORMAT='yyyy-mm-dd hh24:mi:ss'
export exp_date=`date '+%Y%m%d'`
pg_dump -U postgres dbpostgres -f /u01/backup/$exp_date.sql
gzip -1 /u01/backup/$exp_date.sql #壓縮備份檔案
find /u01/backup -mtime +14 -exec rm {} \; #刪除七天前備份檔案
3.4 mongoDB資料庫
#!/bin/sh
DUMP=/home/webapp/Downloads/mongoDB/mongodbserver/bin/mongodump #mongodump備份檔案執行路徑
OUT_DIR=/home/webapp/backup/mongo_bak/mongod_bak_now #臨時備份目錄
TAR_DIR=/home/webapp/backup/mongo_bak/mongod_bak_list #備份存放路徑
DATE=`date +%Y_%m_%d_%H_%M_%S` #獲取當前系統時間
DB_USER=XXXX#資料庫賬號
DB_PASS=XXXX #資料庫密碼
DB_NAME=TEST #資料庫名稱
IP=xx.xx.xx.xx:27017
DAYS=365 #DAYS=30代表刪除30天前的備份,即只保留最近30天的備份
TAR_BAK="mongod_bak_$DATE.tar.gz" #最終儲存的資料庫備份檔名
cd $OUT_DIR
rm -rf $OUT_DIR
mkdir -p $OUT_DIR/$DATE
$DUMP -h $IP -u $DB_USER -p $DB_PASS -d $DB_NAME -o $OUT_DIR/$DATE #備份資料庫
tar -zcvf $TAR_DIR/$TAR_BAK $OUT_DIR/$DATE #壓縮為.tar.gz格式
find $TAR_DIR/ -mtime +$DAYS -delete #刪除30天前的備份
exit
4 定時備份資料庫實際操作
每天凌晨1點備份以上常見資料庫
① 建立備份指令碼
在home路徑下建立backup.sh 並新增以上資料庫備份shell指令碼
[root@xiezhr home]# vim /home/bakcup/backup.sh
# 要備份那個資料庫,就往backup.sh 新增對應的shell指令碼即可
③ 給指令碼增加執行許可權
[root@xiezhr home]# chmod u+x /home/bakcup/backup.sh
③ 設定定時任務crontab
[root@xiezhr home]# crontab -e
0 1 * * * /home/bakcup/backup.sh
本期到此就結束了,下一期我們說一說winserver環境下資料庫備份。
敬請期待哦 (●'◡'●)