Shell 備份 網站資料, config, 資料庫
本篇來介紹備份伺服器的重要資料,在 Linux 備份資料有很多種方法可以達成,本文將著重於使用 Shell script 備份網站資料、資料庫及重要設定檔的流程與程式步驟進行說明。
本文中的 shell script 也有放在 GitHub,歡迎有需要的人可以直接去下載使用。https://github.com/PoLun-Wang/ServerBackup
由於這種備份資料的方法可能會將一些重要資訊記錄在 shell script 中,因此建議將檔案權限設定改成 700 會比較好。
完整備份可以分為兩大步驟:1.備份現有資料,2.依據刪除舊資料邏輯移除舊資料(端看備份要保留多久時間)
差異備份的話就會更複雜了,會包含多久做一次差異備份、完整備份,製作完整備份之後,還要在完整備份的基礎之上進行差異備份諸如此類的步驟。(差異備份的做法有碰到的話再整理上來說明)
本篇會以較為簡單的完整備份來跟各位說明、介紹事先撰寫好的 shell script。
依照完整備份的流程構思本次要介紹的備份小程式:
1.宣告全域變數 -> 2.宣告備份函數 -> 3.呼叫備份函數
- 宣告全域變數:包括備份檔存放位置、shell 執行過程中的 log 路徑、資料庫帳號、資料庫密碼、現在時間、現在日期、預計要刪除舊備份檔的日期,因為本範例是保留5日的備份檔,因此以日期作為備份檔名的一部分,若備份頻率更高的話便需要再調整程式以符合需求。
- 宣告備份函數:備份函數內會執行的項目包含備份指定站台目錄、設定檔、設定檔目錄、資料庫,然而將這些動作包裝在函數裡面的理由很簡單,希望函數接收到不同的參數後,能以此備份不同的目標來提高可用度。
- 呼叫備份函數:因為備份函數可以替換備份目標,因此需要在呼叫函數時傳入整卻的參數即可。
下列為備份站台用的 shell script,在 github 上的檔名為“website_bak.sh”。
- 1~7行:屬於變數宣告的區塊,這幾個變數在此宣告都將以全域變數的形式存在。SITE_DIR和LOG_FILE是必定要修改的變數。
- 13~16行:在處理備份函數接收到的參數,並且將之結合一開始就宣告好的日期變數(CURR_DATE, DEL_DATE)組合成相對應的檔名。
- 23~28行:針對執行備份的時進行錯誤處理,避免錯誤發生而無從得知且造成備份作業中斷。
- 52~61行:呼叫備份函數以及第一、第二個參數的用途,其中第一個是欲備份站台的資料夾名稱,第二則是該站台的網域名稱,傳入網域的用意是用來記錄在 log 內作為識別用途。傳入參數也是必修改的項目。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
#!/bin/bash SITE_DIR='/home/poweruser/MY_BAKUP/websites' LOG_FILE='/home/poweruser/MY_BAKUP/backup_log' CURR_TIME=`date +%Y-%m-%d\ %T` CURR_DATE=`date +%Y-%m-%d` DEL_DATE=`date --date='5 days ago' +%Y-%m-%d` echo '==============================================' >> $LOG_FILE echo "Begin of shell script. Time:${CURR_TIME}" >> $LOG_FILE function BACKUP(){ local WEBSITE_FOLDER_NAME=$1 local WEBSITE_DOMAIN=$2 NEW_FILE="${WEBSITE_FOLDER_NAME}_${CURR_DATE}.tar.gz" OLD_FILE="${WEBSITE_FOLDER_NAME}_${DEL_DATE}.tar.gz" CURR_TIME=`date +%Y-%m-%d\ %T` echo '----------------------------------------------' >> $LOG_FILE echo "Backup WEBSITE: Time:${CURR_TIME} -> ${WEBSITE_FOLDER_NAME}(${WEBSITE_DOMAIN}) ..." >> $LOG_FILE ## Try catch { tar -czf $SITE_DIR/$NEW_FILE $WEBSITE_FOLDER_NAME } || { CURR_TIME=`date +%Y-%m-%d\ %T` echo "Result:Failure. Time:${CURR_TIME}, Error when executing tar. The backup file path should be: ${SITE_DIR}/${NEW_FILE}" >> $LOG_FILE } CURR_TIME=`date +%Y-%m-%d\ %T` ## Check old backup exists. if [ -f "${SITE_DIR}/${OLD_FILE}" ] then rm -f $SITE_DIR/$OLD_FILE echo "Delete old backup Success. File:${OLD_FILE}" >> $LOG_FILE fi CURR_TIME=`date +%Y-%m-%d\ %T` if [ -f "${SITE_DIR}/${NEW_FILE}" ] then echo "Result:Success. Time:${CURR_TIME} Path:${SITE_DIR}/${NEW_FILE}" >> $LOG_FILE else echo "Result:Failure. Time:${CURR_TIME} Path:${SITE_DIR}/${NEW_FILE}" >> $LOG_FILE fi return 1 } ## Call backup section. ## Backup Websites ## Parameter1: Website folder name. ## Parameter2: Website domain name for displaying in log file. ## Switch in your website's folder. cd /var/www BACKUP 'myWordPress' 'www.brilliantcode.net' BACKUP 'myTestingWordPress' 'testing.brilliantcode.net' BACKUP 'phpMyAdmin' 'phpMyAdmin.brilliantcode.net' CURR_TIME=`date +%Y-%m-%d\ %T` echo "End of shell script. Time:${CURR_TIME}" >> $LOG_FILE |
下列為備份設定檔的 shell script,在 github 上的檔名為“config_bak.sh”。
這個 shell 程式重要的區塊與流程跟『備份站台』的概念是一樣的,因此我就直接列出對你來說可能需要修改的地方:
- CNF_DIR, LOG_FILE:改成你自己的備份目錄和 log 檔名稱。
- 52~76行:呼叫備份設定檔之前,記得切換到正確的目錄。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
#!/bin/bash CNF_DIR='/home/poweruser/MY_BAKUP/configs' LOG_FILE='/home/poweruser/MY_BAKUP/backup_log' CURR_TIME=`date +%Y-%m-%d\ %T` CURR_DATE=`date +%Y-%m-%d` DEL_DATE=`date --date='5 days ago' +%Y-%m-%d` echo '==============================================' >> $LOG_FILE echo "Begin of shell script. Time:${CURR_TIME}" >> $LOG_FILE function BACKUP(){ local BAK_TARGET=$1 local BAK_FILE_NAME=$2 local BAK_TYPE_ID=$3 NEW_FILE="${BAK_FILE_NAME}_${CURR_DATE}.tar.gz" OLD_FILE="${BAK_FILE_NAME}_${DEL_DATE}.tar.gz" CURR_TIME=`date +%Y-%m-%d\ %T` echo '----------------------------------------------' >> $LOG_FILE echo "Backup CONFIG : Time:${CURR_TIME} -> ${BAK_TYPE_ID} ..." >> $LOG_FILE ## Try-catch { # Should cd to the folder that contains configs before you call BACKUP function. tar -czf $CNF_DIR/$NEW_FILE $BAK_TARGET } || { CURR_TIME=`date +%Y-%m-%d\ %T` echo "Result:Failure. Time:${CURR_TIME}, Error when executing tar. The backup file path should be: ${CNF_DIR}/${NEW_FILE}" >> $LOG_FILE } CURR_TIME=`date +%Y-%m-%d\ %T` if [ -f "$CNF_DIR/$OLD_FILE" ] then rm -f $CNF_DIR/$OLD_FILE echo "Delete old backup Success. File:${OLD_FILE}" >> $LOG_FILE fi CURR_TIME=`date +%Y-%m-%d\ %T` if [ -f "${CNF_DIR}/${NEW_FILE}" ] then echo "Result:Success. Time:${CURR_TIME} Path:${CNF_DIR}/${NEW_FILE}" >> $LOG_FILE else echo "Result:Failure. Time:${CURR_TIME} Path:${CNF_DIR}/${NEW_FILE}" >> $LOG_FILE fi return 1 } ## Call backup section. ## Backup Config ## Parameter1: Configuration folder name or file name. ## Parameter2: The backup file name. ## Parameter3: The display name for writing logs. cd /etc/httpd/ BACKUP 'conf' 'httpd.conf' 'httpd-conf' cd /etc/httpd/ BACKUP 'conf.d' 'httpd.conf.d' 'httpd-conf.d' cd /etc/httpd/ BACKUP 'conf.modules.d' 'httpd.conf.modules.d' 'httpd-conf.modules.d' cd /etc/opt/remi/php73/ BACKUP 'php.ini' 'php-config' 'php-config' cd /etc/ssh/ BACKUP 'sshd_config' 'sshd-config' 'sshd-config' cd /etc/ BACKUP 'my.cnf' 'mysql-config' 'mysql-config' cd /var/spool/ BACKUP 'cron' 'cron-config' 'cron-config' CURR_TIME=`date +%Y-%m-%d\ %T` echo "End of shell script. Time:${CURR_TIME}" >> $LOG_FILE |
下列為備份資料庫的 shell script,在 github 上的檔名為“database_bak.sh”。
需要特別注意的地方應該是 mysqldump 的部分,因為要傳入 MySQL 的帳號密碼,所以要將帳號、密碼儲存在 shell script 裡面,也因為這樣,必須要特別注意 shell script 的檢視權限。
- 第3~6行:DB_USER, DB_PWD分別是 root 的帳密,用 root 是方便備份所有資料庫。
- 第53~58行:呼叫備份函數,傳入的第一個參數與第二個參數分別是欲備份的資料庫以及該資料庫對應到站台的網域名稱,網域名稱的部分則是寫入 log 辨識用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
#!/bin/bash DB_USER='root' DB_PWD='Password of DB root' DB_DIR='/home/poweruser/MY_BAKUP/db' LOG_FILE='/home/poweruser/MY_BAKUP/backup_log' CURR_TIME=`date +%Y-%m-%d\ %T` CURR_DATE=`date +%Y-%m-%d` DEL_DATE=`date --date='5 days ago' +%Y-%m-%d` echo '==============================================' >> $LOG_FILE echo "Begin of shell script. Time:${CURR_TIME}" >> $LOG_FILE function BACKUP(){ local DB_NAME=$1 local WEBSITE_DOMAIN=$2 NEW_FILE="${DB_NAME}_${CURR_DATE}.sql" OLD_FILE="${DB_NAME}_${DEL_DATE}.sql" CURR_TIME=`date +%Y-%m-%d\ %T` echo '----------------------------------------------' >> $LOG_FILE echo "Backup DB : Time:${CURR_TIME} -> ${DB_NAME}(${WEBSITE_DOMAIN}) ..." >> $LOG_FILE ## Try-catch { mysqldump -u$DB_USER -p$DB_PWD $DB_NAME > $DB_DIR/$NEW_FILE } || { CURR_TIME=`date +%Y-%m-%d\ %T` echo "Result:Failure. Date:${CURR_TIME}, Error when executing mysqldump. Database:${DB_NAME}" >> $LOG_FILE } CURR_TIME=`date +%Y-%m-%d\ %T` ## Check old backup exists. if [ -f "${DB_DIR}/${OLD_FILE}" ] then rm -f $DB_DIR/$OLD_FILE echo "Delete old backup Success. File:${OLD_FILE}" >> $LOG_FILE fi CURR_TIME=`date +%Y-%m-%d\ %T` if [ -f "${DB_DIR}/${NEW_FILE}" ] then echo "Result:Success. Time:${CURR_TIME} Path:${DB_DIR}/${NEW_FILE}" >> $LOG_FILE else echo "Result:Failure. Time:${CURR_TIME} Path:${DB_DIR}/${NEW_FILE}" >> $LOG_FILE fi return 1 } ## Call backup section. ## Backup Database ## Parameter1: Database name. ## Parameter2: The domain name related to this database. BACKUP 'wordpress_db' 'www.brilliantcode.net' BACKUP 'wp_testing_db' 'testing.brilliantcode.net' CURR_TIME=`date +%Y-%m-%d\ %T` echo "End of shell script. Time:${CURR_TIME}" >> $LOG_FILE |
Pingback:CentOS 8 架站教學彙整 - BrilliantCode.net