11. shell多執行緒備份資料庫

最愛喝酸奶發表於2019-01-29

也許你會有疑問,shell這麼簡單的指令碼語言有多執行緒一說嗎?答案是有的,只不過它實現起來有些難理解罷了,因為它藉助了命名管道實現。所謂多執行緒就是將原來由一個程式完成的事情現在由多個執行緒去完成。假如一個程式需要10個小時完成的事情,現在分配給10個執行緒,給它們分工,然後同時去做這件事情,最終可能就需要1個小時。

本案例就是實現shell多執行緒備份資料庫,具體要求如下:

1)公司的業務量比較大,有100個資料庫需要全量備份,而每個資料庫的資料量高達幾十GB
  (注意:每一個庫都為一個獨立的例項,即有著獨立的ip:port);
  
2)預估每一個庫的備份時間為30分鐘左右,要求在5個小時內完成;

3)假設100個庫的庫名、host、port以及配置檔案路徑都存到一個檔案裡,檔名字為 /tmp/databases.list ;

4)格式為:db1 10.10.10.2 3308 /data/mysql/db1/my.cnf 。

要想在5小時內完成100個資料庫的備份,需要使用shell指令碼的多執行緒功能,一次性開10個執行緒同時併發備份10個資料庫。

參考指令碼如下:

#!/bin/bash
#多執行緒備份資料庫
#備份資料庫使用xtrabackup(由於涉及到myisam,命令為innobackupex)

exec &> /tmp/mysql_bak.log

if ! which inoobackupex &>/dev/null
then
    echo "安裝xtrabackup工具"
    yum install https://repo.percona.com/yum/percona-release-latest.noarch.rpm
    yum install percona-xtrabackup-24
    
    if [ $? -ne 0 ]
    then
        echo -e "\033[31m安裝xtrabackup工具出錯,請檢查\033[0m"
        exit 1
    fi
fi

bakdir=/data/backup/mysql
bakuser=vyNctM
bakpass=99omeaBHh

bak_data()
{
    db_name=$1
    db_host=$2
    db_port=$3
    cnf=$4
    
    [ -d $bakdir/$db_name ] || mkdir -p $bakdir/$db_name
    innobackupex --defaults-file=$4 --host=$2 --port=$3 --user=$bakuser --password=$bakpass --databases=$1 $bakdir
    
    if [ $? -ne 0 ]
    then
        echo -e "\033[31m備份資料庫$1出現問題\033[0m"
    fi
}

fifofile=/tmp/$$
mkfifo $fifofile
exec 1000<>$fifofile

n=10
for ((i=0;i<$n;i++))
do
    echo >&1000         # 0-9,建立10個執行緒
done

cat /tmp/databases.list |while read line
do
    read -u1000
    {
        bak_data `echo $line`
        echo >&1000
    } &
done

wait
exec 1000>&-        #刪除fd1000
rm -f $fifofile     #刪除命名管道

指令碼中,

  1. exec &> /tmp/mysql_bak.log ,將正確輸出和錯誤輸出都重定向到 /tmp/mysql_bak.log

  2. $$表示本程式PID,mkfifo命令建立命名管道

  3. read line ,line為變數名,將接下來的輸入賦值給line


相關文章