這篇文章主要為大家展示了“MySQLdump5.7以下版本如何實(shí)現(xiàn)并發(fā)備份”,內(nèi)容簡(jiǎn)而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領(lǐng)大家一起研究并學(xué)習(xí)一下“mysqldump5.7以下版本如何實(shí)現(xiàn)并發(fā)備份”這篇文章吧。
創(chuàng)新互聯(lián)專注于銀川企業(yè)網(wǎng)站建設(shè),成都響應(yīng)式網(wǎng)站建設(shè)公司,商城網(wǎng)站開(kāi)發(fā)。銀川網(wǎng)站建設(shè)公司,為銀川等地區(qū)提供建站服務(wù)。全流程定制開(kāi)發(fā),專業(yè)設(shè)計(jì),全程項(xiàng)目跟蹤,創(chuàng)新互聯(lián)專業(yè)和態(tài)度為您提供的服務(wù)
mysqldump適用于備份單表,或者數(shù)量級(jí)較小的庫(kù)的備份。一般情況下innobackupex備份數(shù)量級(jí)大的庫(kù),速度是很快的。但是其瓶頸在于如果業(yè)務(wù)需要多實(shí)例部分對(duì)象遷移到新的實(shí)例里,此時(shí)就無(wú)法滿足該情況。(mysqldumper在此不做討論)。
下面簡(jiǎn)單列舉mysqldump適用的場(chǎng)景:
備份多個(gè)單表
備份一個(gè)或多個(gè)庫(kù)
備份存儲(chǔ)過(guò)程、自定義函數(shù)或事件
只備份數(shù)據(jù)不備份表結(jié)構(gòu)
只備份表結(jié)構(gòu)不備份數(shù)據(jù)
其他
mysqldump雖然使用起來(lái)比較靈活,但是它無(wú)法實(shí)現(xiàn)并發(fā)備份,故本文描述的就是實(shí)現(xiàn)如何用mysqldump實(shí)現(xiàn)并發(fā)備份
把需要備份的一個(gè)庫(kù)或多個(gè)庫(kù),提取這些庫(kù)下面所有的表進(jìn)行一個(gè)個(gè)備份:這樣可以利用腳本進(jìn)行多線程備份這些單表,從而實(shí)現(xiàn)庫(kù)級(jí)的并發(fā)備份。
點(diǎn)擊(此處)折疊或打開(kāi)
#!/bin/bash
#注釋:mysqldump多線程備份多表
#Auther:cyt
#date:2016-06-23
#按照多實(shí)例循環(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)大(備份完后會(huì)調(diào)?。?/p>
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 "-----端口號(hào)為"$port"的mysql實(shí)例開(kāi)始按表并發(fā)備份:開(kāi)始時(shí)間為"`date "+%Y-%m-%d %H:%M:%S"`
#調(diào)用備份函數(shù)
dumpAllTable
#計(jì)算備份所用時(shí)間
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 '-----端口號(hào)為'$port'的mysql實(shí)例于' $END '備份完成,使用時(shí)間為 '$TIME_INVENTAL_M'分鐘'$TIME_INVENTAL_S'秒'
#調(diào)用tardump函數(shù),對(duì)備份文件進(jìn)行壓縮,注意本次壓縮會(huì)刪掉原文件
tardump
#將參數(shù)改為默認(rèn),以防耗盡內(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
#過(guò)濾掉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ù)實(shí)現(xiàn)多線程備份
function dumpAllTable()
{
local schemaFile="${BACKUP_DIR}/cyt.log"
#最大的表先備份(因多進(jìn)程并發(fā),最短完成時(shí)間依賴于最大表的完成)
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
#從管道取出一個(gè)空格(如無(wú)空格則阻塞,達(dá)到控制并發(fā)的目的)
read -u6
#命令執(zhí)行完后壓回一個(gè)空格
{ eval $2;echo >&6; } & #> /dev/null 2>&1 &
shift
cmd=$2
done
#等待所有的后臺(tái)子進(jìn)程結(jié)束
wait
#關(guān)閉df6
exec 6>&-
}
#壓縮備份文件
function tardump()
{
#使用tar壓縮
if [ -d ${BACKUP_DIR} ] && [ -n ${port} ]
then
echo "-----開(kāi)始進(jìn)行壓縮端口號(hào)為"$port"的mysql實(shí)例的備份:開(kāi)始時(shí)間"`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 "沒(méi)有可以進(jìn)行壓縮的文件";
fi;
echo "-----壓縮端口號(hào)為"$port"的mysql實(shí)例的備份文件:結(jié)束時(shí)間"`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í)例本地用戶密碼問(wèn)題需注意)
#數(shù)據(jù)庫(kù)用戶
DB_USER='cyt'
#數(shù)據(jù)庫(kù)用戶對(duì)應(yīng)的密碼
DB_PASSWORD='cyt'
#記錄開(kāi)始的時(shí)間
BEGIN=`date "+%Y-%m-%d %H:%M:%S"`
BEGIN_T=`date -d "$BEGIN" +%s`
echo '--------------開(kāi)始按表并發(fā)備份:開(kāi)始時(shí)間為 '$BEGIN
#設(shè)置并發(fā)備份的線程數(shù)
threadsNum=10
#調(diào)用instance函數(shù)
instance
echo '--------------backup all database successfully?。?!結(jié)束時(shí)間:' `date "+%Y-%m-%d %H:%M:%S"`
}
main
由于該腳本是并行備份,以防由于繁忙,導(dǎo)致獲取不到dump連接,故將該參數(shù)調(diào)大(該數(shù)據(jù)庫(kù)版本是5.6.19,腳本在備份完后會(huì)調(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日志里,然后通過(guò)并發(fā)函數(shù)execConcurrency和數(shù)組dumpAllTable來(lái)實(shí)現(xiàn)本腳本的目的
本腳本可以實(shí)現(xiàn)多實(shí)例備份,如果多實(shí)例備份的用戶名和密碼不同,可以使用case命令,下面是簡(jiǎn)單舉例
點(diǎn)擊(此處)折疊或打開(kāi)
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以下版本如何實(shí)現(xiàn)并發(fā)備份”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對(duì)大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!