Linux下Mysql的資料庫備份(基於 CentOS 7.4 64位)
在做專案的時候,經常會需要對資料庫進行備份,基於Linux系統下的操作我還是第一次做,所以在網上查詢了很多資料,分別參考了https://www.cnblogs.com/batsing/p/4938986.html 和 https://www.cnblogs.com/ityouknow/p/5923489.html的配置,探索的過程總是艱辛的,並不是那麼一帆風順,期間遇到了很多問題,下面我會給出指令碼和在使用過程中遇到的問題。話不多說,直接看過程吧。
一、mysql提供了一個mysqldump的工具可以方便的匯出匯入資料庫資訊;
二、使用命令列shell測試執行mysqldump,理解必備的引數,檢視生成的sql備份檔案是否符合需求;
$BIN_DIR/mysqldump --opt -u$DB_USER -p$DB_PASS -h$DB_HOST $DB_ZFBM $DB_NAME $DB_TABLE > $BCK_DIR/db_$DATE.sql
指令碼說明:
$BIN_DIR mysql備份地址
$DB_USER 資料庫使用者名稱
$DB_PASS 資料庫密碼
$DB_HOST 資料庫地址(IP或者是localhost之類的)
$DB_ZFBM 字符集編碼設定(這個很關鍵,解決匯出檔案中中文亂碼)
$DB_NAME 資料庫名稱
$DB_TABLE 要備份的表名(如果只對單一表進行備份,可以加此欄位,全庫備份的可以省略掉)
$BCK_DIR/db_$DATE.sql 備份的地址和備份檔名稱
三、下面是我親自試驗過得,在兩位前輩的基礎上加以修改過的指令碼
#!/bin/bash # Name:bakmysql.sh # This is a ShellScript For Auto DB Backup and Delete old Backup # # Database info DB_USER="root" #mysql login name DB_PASS="123456" #password DB_HOST="localhost" #db_address DB_NAME="bosh_education" #db_name DB_ZFBM="--default-character-set=utf8" #character DB_TABLE="exam_quest_bank" #table name # Others vars BIN_DIR="/usr/bin" #the mysql bin path BCK_DIR="/usr/mysqlbeifen" #the backup file directory DATE=`date +%F` #--skip-lock-tables zg backup #$BIN_DIR/mysqldump -u $DB_USER -p$DB_PASS $DB_ZFBM $DB_NAME $DB_TABLE | gzip > $BCK_DIR/db_$DATE.sql.gz #sql back $BIN_DIR/mysqldump --opt -u$DB_USER -p$DB_PASS -h$DB_HOST $DB_ZFBM $DB_NAME $DB_TABLE > $BCK_DIR/db_$DATE.sql # find $BCK_DIR -name "db_*.sql" -type f -mtime +3 -exec rm {} \; > /dev/null 2>&1 #
完成檔案後儲存並上傳到指定的目錄下(/usr/local/apache/htdocs/timepusher/sqlBak/)如下圖所示:
四、測試指令碼是否可用
1、進入到該指令碼檔案目錄
cd /usr/local/apache/htdocs/timepusher/sqlBak
2、給剛才的指令碼附加許可權(否則會報錯 Permission denied )
chmod +x bakmysql.sh
3、在此目錄下執行指令碼,驗證指令碼是否正確
./bakmysql.sh
此時我也遇到了前面兩位筆者提到的錯誤,提示如下:
/bin/sh^M: bad interpreter: No such file or directory
這是因為在windows編寫上傳的檔案導致,是不同系統編碼格式引起的:在 windows系統中編輯的 .sh檔案可能有不可見字元,所以在 Linux系統下執行會報以上異常資訊。可以在Windows上使用Notepad++轉換成Unix格式(選單中選擇:編輯>檔案格式轉換>轉換成UNIX),按照此不方法操作後即可正常執行了。操作如下:
4、修改後上傳繼續執行 ./bakmysql.sh ,沒有報錯。再檢視匯出的sql檔案。如下圖所示:
到此就完成了所有的指令碼編寫和測試。下面再詳細說一下匯出時候的指令碼語言:
$BIN_DIR/mysqldump -u $DB_USER -p$DB_PASS $DB_ZFBM $DB_NAME $DB_TABLE | gzip > $BCK_DIR/db_$DATE.sql.gz
$BIN_DIR/mysqldump -u $DB_USER -p$DB_PASS $DB_ZFBM $DB_NAME | gzip > $BCK_DIR/db_$DATE.sql.gz
由於匯出整個資料的檔案較大,所以建議使用壓縮檔案的形式,上述是匯出壓縮檔案的指令碼,加上表名($DB_TABLE)可以指定表匯出,不加表名的匯出整個資料庫表,根據自己的情況實際使用。直接匯出sql檔案的也是這個道理,就不細說了。
由於每天定時備份資料庫,會導致很佔記憶體,所以此處也給出了定時刪除備份資料庫的指令碼,如下所示:
find $BCK_DIR -name "db_*.sql" -type f -mtime +3 -exec rm {} \; > /dev/null 2>&1
解釋一下:
-type f 表示查詢普通型別的檔案,f表示普通檔案。
-mtime +3 按照檔案的更改時間來查詢檔案,+3表示檔案更改時間距現在3天以前;如果是 -mmin +5 表示檔案更改時間距現在5分鐘以前。
-exec rm {} \; 表示執行一段shell命令,exec選項後面跟隨著所要執行的命令或指令碼,然後是一對兒{},一個空格和一個,最後是一個分號。
/dev/null 2>&1 把標準出錯重定向到標準輸出,然後扔到/DEV/NULL下面去。通俗的說,就是把所有標準輸出和標準出錯都扔到垃圾桶裡面;其中的& 表示讓該命令在後臺執行。
五、定時指令碼的編寫
1、編輯定時任務列表
crontab -e
如下圖所示:
2、按【i】鍵進入編輯許可權,插入如下指令碼,按【Esc】後輸入:wq即可儲存退出編輯了:
#每天早上 5:00am 執行
00 05 * * * /bin/sh /usr/local/apache/htdocs/timepusher/sqlBak/bakmysql.sh
定時的一些說明:
crontab配置檔案格式如下:
分 時 日 月 周 命令
3、檢視設定的定時任務是否成功:
crontab -l
如下圖所示:
4、重啟crontab(分別有給出了別的操作命令)
#重啟
/bin/systemctl restart crond.service
#開啟
/bin/systemctl start crond.service
#停止
/bin/systemctl stop crond.service
#過載
/bin/systemctl reload crond.service
#狀態
/bin/systemctl status crond.service
六、第二天記得檢查是否備份成功(也可以改時間校驗,自己決定)
如果生成的檔案和解壓出來檢視沒有問題,那麼這個自動定時備份資料庫的指令碼就算是完成了。
像前面了兩位筆者致敬,我是站在巨人的肩膀上完成的任務,這是我第一次搞這個,所以參考的比較多,像第一位筆者出現的最後一個問題,我是沒遇到,可以先記下來,方便以後出問題的時候檢視:
問題描述為:如果該資料庫的使用者沒有分配 鎖表 的許可權,則備份會報錯 when using LOCK TABLES 。那是因為mysqldump命令預設在匯出時是要鎖定表的,所以解決方式有兩個。一個是給該使用者開放 鎖表 的許可權;另一個是在命令中加上 --skip-lock-tables 這個引數。即是:
$BIN_DIR/mysqldump --opt -u$DB_USER -p$DB_PASS -h$DB_HOST $DB_NAME --skip-lock-tables| gzip > $BCK_DIR/db_$DATE.sql.gz
留此貼以方便之後自己檢視!!