1. 程式人生 > >Linux下Mysql的資料庫備份(基於 CentOS 7.4 64位)

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

留此貼以方便之後自己檢視!!