您好,登錄后才能下訂單哦!
這篇文章主要為大家展示了“mysqldump5.7以下版本如何實現(xiàn)并發(fā)備份”,內(nèi)容簡而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領(lǐng)大家一起研究并學(xué)習(xí)一下“mysqldump5.7以下版本如何實現(xiàn)并發(fā)備份”這篇文章吧。
mysqldump適用于備份單表,或者數(shù)量級較小的庫的備份。一般情況下innobackupex備份數(shù)量級大的庫,速度是很快的。但是其瓶頸在于如果業(yè)務(wù)需要多實例部分對象遷移到新的實例里,此時就無法滿足該情況。(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<=NF;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<=NF;i++){if($i~/socket=/) print gsub(/--socket=/,""),$i}}' | awk '{print $2}'`
#由于該腳本是并行備份,以防由于繁忙,導(dǎo)致獲取不到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 >&6; } & #> /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ù)庫用戶對應(yīng)的密碼
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
由于該腳本是并行備份,以防由于繁忙,導(dǎo)致獲取不到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ù),將要使用的命令導(dǎo)入到${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)容對大家有所幫助,如果還想學(xué)習(xí)更多知識,歡迎關(guān)注億速云行業(yè)資訊頻道!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。