資料庫定時備份linux篇

2023-05-12 09:00:42

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環境下資料庫備份。

敬請期待哦 (●'◡'●)