共計 4471 個字符,預計需要花費 12 分鐘才能閱讀完成。
這篇文章主要為大家展示了“mysqldump5.7 以下版本如何實現(xiàn)并發(fā)備份”,內(nèi)容簡而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓丸趣 TV 小編帶領(lǐng)大家一起研究并學習一下“mysqldump5.7 以下版本如何實現(xiàn)并發(fā)備份”這篇文章吧。
mysqldump5.7 以下版本多線程備份單表
【背景說明】
mysqldump 適用于備份單表,或者數(shù)量級較小的庫的備份。一般情況下 innobackupex 備份數(shù)量級大的庫,速度是很快的。但是其瓶頸在于如果業(yè)務需要多實例部分對象遷移到新的實例里,此時就無法滿足該情況。(mysqldumper 在此不做討論)。
下面簡單列舉 mysqldump 適用的場景:
備份多個單表
備份一個或多個庫
備份存儲過程、自定義函數(shù)或事件
只備份數(shù)據(jù)不備份表結(jié)構(gòu)
只備份表結(jié)構(gòu)不備份數(shù)據(jù)
其他
mysqldump 雖然使用起來比較靈活,但是它無法實現(xiàn)并發(fā)備份,故本文描述的就是實現(xiàn)如何用 mysqldump 實現(xiàn)并發(fā)備份
【思路說明】
把需要備份的一個庫或多個庫,提取這些庫下面所有的表進行一個個備份:這樣可以利用腳本進行多線程備份這些單表,從而實現(xiàn)庫級的并發(fā)備份。
【具體腳本】
點擊 (此處) 折疊或打開
#!/bin/bash
#注釋:mysqldump 多線程備份多表
#Auther:cyt
#date:2016-06-23
#按照多實例循環(huán)框架
function instance()
{
for port in `ps -ef | grep -v -E mysqld_safe|awk | awk /mysqld /,/port=/ {for(i=1;i i++){if($i~/port=/) print gsub(/–port=/,),$i}} | awk {print $2} `
do
## 避免循環(huán)的 port 和 sock 不匹配
sock=`ps -ef | grep ${port} | grep -v -E mysqld_safe|awk | awk /mysqld /,/socket=/ {for(i=1;i i++){if($i~/socket=/) print gsub(/–socket=/,),$i}} | awk {print $2} `
# 由于該腳本是并行備份,以防由于繁忙,導致獲取不到 dump 連接,故將該參數(shù)調(diào)大(備份完后會調(diào)小)
mysql -u$DB_USER -p$DB_PASSWORD –host= –socket=$sock –host=$host -BN -e SET GLOBAL net_write_timeout=1800
# 調(diào)用輸出備份命令的日志函數(shù)
log
echo —– 端口號為 $port 的 mysql 實例開始按表并發(fā)備份: 開始時間為 `date +%Y-%m-%d %H:%M:%S `
# 調(diào)用備份函數(shù)
dumpAllTable
# 計算備份所用時間
END=`date +%Y-%m-%d %H:%M:%S `
END_T=`date -d $END +%s`
TIME_INVENTAL_M=$[($END_T-$BEGIN_T)/60]
TIME_INVENTAL_S=$[($END_T-$BEGIN_T)%60]
echo —– 端口號為 $port 的 mysql 實例于 $END 備份完成,使用時間為 $TIME_INVENTAL_M 分鐘 $TIME_INVENTAL_S 秒
# 調(diào)用 tardump 函數(shù),對備份文件進行壓縮,注意本次壓縮會刪掉原文件
tardump
# 將參數(shù)改為默認,以防耗盡內(nèi)存
mysql -u$DB_USER -p$DB_PASSWORD –host= –socket=$sock –host=$host -BN -e SET GLOBAL net_write_timeout=60
done
}
#將要備份的單表從大到小輸出到日志里面
function log()
{
BACKUP_DIR=/data/backup/$DATE/$port;
mkdir -p $BACKUP_DIR
# 過濾掉 MySQL 自帶的 DB
if [-e ${BACKUP_DIR}/cyt.log ];
then rm -rf ${BACKUP_DIR}/cyt.log;
fi;
for a in `mysql -u$DB_USER -p$DB_PASSWORD –socket=$sock –host=$host -BN -e show databases; |sed /^performance_schema$/ d|sed /^mysql/ d |sed /^information_schema$/ d|sed /^information_schema$/ d|sed /^test$/ d|sed /^sys$/ d `
do
mkdir -p ${BACKUP_DIR}/${a}
for j in `mysql -u$DB_USER -p$DB_PASSWORD –host= –socket=$sock –host=$host -BN -e select table_name from information_schema.tables where table_schema= ${a} order by table_rows desc; `
do
echo mysqldump -u $DB_USER -p $DB_PASSWORD –socket= $sock –host= $host –set-gtid-purged=OFF -c –single_transaction=OFF -q –skip-add-locks ${a} ${j} $BACKUP_DIR / ${a} / ${j} .sql $BACKUP_DIR/cyt.log;
done
done
}
#調(diào)用函數(shù) log,查看 log 日志調(diào)用并發(fā)函數(shù)實現(xiàn)多線程備份
function dumpAllTable()
{
local schemaFile= ${BACKUP_DIR}/cyt.log
# 最大的表先備份(因多進程并發(fā),最短完成時間依賴于最大表的完成)
allTable=`cat $schemaFile | wc -l`
i_import=0
declare -a array_cmds
i_array=0
while read file; do
i_import=`expr $i + 1`
array_cmds[i_array]= ${file}
i_array=`expr ${i_array} + 1`
done ${BACKUP_DIR}/cyt.log
execConcurrency ${threadsNum} ${array_cmds[@]}
}
#并發(fā)函數(shù)
function execConcurrency()
{
# 并發(fā)數(shù)據(jù)量
local thread=$1
# 并發(fā)命令
local cmd=$2
# 定義管道,用于控制并發(fā)線程
tmp_fifofile= /tmp/$$.fifo
mkfifo $tmp_fifofile
# 輸入輸出重定向到文件描述符 6
exec 6 $tmp_fifofile
rm -f $tmp_fifofile
# 向管道壓入指定數(shù)據(jù)的空格
for ((i=0;i $thread;i++)); do
echo
done 6
# 遍歷命令列表
while [$cmd]; do
# 從管道取出一個空格(如無空格則阻塞,達到控制并發(fā)的目的)
read -u6
# 命令執(zhí)行完后壓回一個空格
{eval $2;echo} # /dev/null 2 1
shift
cmd=$2
done
# 等待所有的后臺子進程結(jié)束
wait
# 關(guān)閉 df6
exec 6 –
}
#壓縮備份文件
function tardump()
{
# 使用 tar 壓縮
if [-d ${BACKUP_DIR} ] [-n ${port} ]
then
echo —– 開始進行壓縮端口號為 $port 的 mysql 實例的備份:開始時間 `date +%Y-%m-%d %H:%M:%S `
cd $BACKUP_DIR;
for b in `find $BACKUP_DIR -maxdepth 1 -type d ! -iname ${port}* ! -iname *.sql ! -iname *tar.gz `
do
c=`basename $b`
tar -zcvf $c _ $(date +%F_%H-%M).tar.gz $c –remove-files /dev/null
done
else echo 沒有可以進行壓縮的文件
fi;
echo —– 壓縮端口號為 $port 的 mysql 實例的備份文件:結(jié)束時間 `date +%Y-%m-%d %H:%M:%S `
}
#主函數(shù)
function main()
{
# 獲取本地 IP 地址
host=`ifconfig | grep inet addr: | grep -v 127.0.0.1 | cut -d: -f2 | awk {print $1} `
DATE=`date +%F`
# 本次備份 mysqldump –host –socket 如果是本地用戶備份,建議去掉 host;(多實例本地用戶密碼問題需注意)
# 數(shù)據(jù)庫用戶
DB_USER= cyt
# 數(shù)據(jù)庫用戶對應的密碼
DB_PASSWORD= cyt
# 記錄開始的時間
BEGIN=`date +%Y-%m-%d %H:%M:%S `
BEGIN_T=`date -d $BEGIN +%s`
echo ————– 開始按表并發(fā)備份: 開始時間為 $BEGIN
# 設(shè)置并發(fā)備份的線程數(shù)
threadsNum=10
# 調(diào)用 instance 函數(shù)
instance
echo ————–backup all database successfully!!!結(jié)束時間: `date +%Y-%m-%d %H:%M:%S `
}
main
【腳本說明】
由于該腳本是并行備份,以防由于繁忙,導致獲取不到 dump 連接,故將該參數(shù)調(diào)大(該數(shù)據(jù)庫版本是 5.6.19,腳本在備份完后會調(diào)小)
mysql -u$DBUSER -p$DBPASSWORD –host= –socket=$sock –host=$host -BN -e SET GLOBAL netwritetimeout=1800
由于想要利用并發(fā)函數(shù),將要使用的命令導入到 ${BACKUP_DIR}/cyt.log 日志里,然后通過并發(fā)函數(shù) execConcurrency 和數(shù)組 dumpAllTable 來實現(xiàn)本腳本的目的
本腳本可以實現(xiàn)多實例備份,如果多實例備份的用戶名和密碼不同,可以使用 case 命令, 下面是簡單舉例
點擊 (此處) 折疊或打開
if [$port -eq 3306]; then
case $IP in
10.240.5.11 )
DB_USER= CYT1
DB_PASSWORD= 1
;;
10.240.5.12 )
DB_USER= CYT2
DB_PASSWORD= 2
;;
10.240.5.13 )
DB_PASSWORD= 3
;;
esac
else
DB_PASSWORD= 4
fi
以上是“mysqldump5.7 以下版本如何實現(xiàn)并發(fā)備份”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對大家有所幫助,如果還想學習更多知識,歡迎關(guān)注丸趣 TV 行業(yè)資訊頻道!