加入收藏 | 设为首页 | 会员中心 | 我要投稿 92站长网 (https://www.92zhanzhang.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > MySql教程 > 正文

mysqldump5.7以下版本如何达成并发备份

发布时间:2021-12-28 12:15:26 所属栏目:MySql教程 来源:互联网
导读:这篇文章主要为大家展示了mysqldump5.7以下版本如何实现并发备份,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下mysqldump5.7以下版本如何实现并发备份这篇文章吧。 mysqldump5.7以下版本多线程备份单表 【背景说
这篇文章主要为大家展示了“mysqldump5.7以下版本如何实现并发备份”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“mysqldump5.7以下版本如何实现并发备份”这篇文章吧。
 
mysqldump5.7以下版本多线程备份单表
【背景说明】
mysqldump适用于备份单表,或者数量级较小的库的备份。一般情况下innobackupex备份数量级大的库,速度是很快的。但是其瓶颈在于如果业务需要多实例部分对象迁移到新的实例里,此时就无法满足该情况。(mysqldumper在此不做讨论)。
 
下面简单列举mysqldump适用的场景:
 
备份多个单表
备份一个或多个库
备份存储过程、自定义函数或事件
只备份数据不备份表结构
只备份表结构不备份数据
其他
mysqldump虽然使用起来比较灵活,但是它无法实现并发备份,故本文描述的就是实现如何用mysqldump实现并发备份
 
【思路说明】
把需要备份的一个库或多个库,提取这些库下面所有的表进行一个个备份:这样可以利用脚本进行多线程备份这些单表,从而实现库级的并发备份。
 
【具体脚本】
点击(此处)折叠或打开
 
#!/bin/bash
#注释:mysqldump多线程备份多表
#Auther:cyt
#date:2016-06-23
#按照多实例循环框架
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
             ##避免循环的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}'`
             #由于该脚本是并行备份,以防由于繁忙,导致获取不到dump连接,故将该参数调大(备份完后会调小)
             mysql -u$DB_USER -p$DB_PASSWORD --host= --socket=$sock --host=$host -BN -e "SET GLOBAL net_write_timeout=1800";
             #调用输出备份命令的日志函数
             log
             echo "-----端口号为"$port"的mysql实例开始按表并发备份:开始时间为"`date "+%Y-%m-%d %H:%M:%S"`
             #调用备份函数
             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'秒'
             #调用tardump函数,对备份文件进行压缩,注意本次压缩会删掉原文件
             tardump
             #将参数改为默认,以防耗尽内存
             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
}
   
#调用函数log,查看log日志调用并发函数实现多线程备份
function dumpAllTable()
{
        local schemaFile="${BACKUP_DIR}/cyt.log"
        #最大的表先备份(因多进程并发,最短完成时间依赖于最大表的完成)
        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[@]}"
}
#并发函数
function execConcurrency()
{
        #并发数据量
        local thread=$1
        #并发命令
        local cmd=$2
        #定义管道,用于控制并发线程
        tmp_fifofile="/tmp/$$.fifo"
        mkfifo $tmp_fifofile
        #输入输出重定向到文件描述符6
        exec 6<>$tmp_fifofile
        rm -f $tmp_fifofile
        #向管道压入指定数据的空格
        for ((i=0;i<$thread;i++)); do
                echo
        done >&6
        #遍历命令列表
        while [ "$cmd" ]; do
                #从管道取出一个空格(如无空格则阻塞,达到控制并发的目的)
                read -u6
                #命令执行完后压回一个空格
                { eval $2;echo >&6; } & #> /dev/null 2>&1 &
                shift
                cmd=$2
        done
        #等待所有的后台子进程结束
        wait
        #关闭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实例的备份文件:结束时间"`date "+%Y-%m-%d %H:%M:%S"`
}
#主函数
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;(多实例本地用户密码问题需注意)
        #数据库用户
        DB_USER='cyt'
        #数据库用户对应的密码
        DB_PASSWORD='cyt'
        #记录开始的时间
        BEGIN=`date "+%Y-%m-%d %H:%M:%S"`
        BEGIN_T=`date -d "$BEGIN" +%s`
        echo '--------------开始按表并发备份:开始时间为 '$BEGIN
        #设置并发备份的线程数
        threadsNum=10
        #调用instance函数
        instance
        echo '--------------backup all database successfully!!!结束时间:' `date "+%Y-%m-%d %H:%M:%S"`
}
main
【脚本说明】
由于该脚本是并行备份,以防由于繁忙,导致获取不到dump连接,故将该参数调大(该数据库版本是5.6.19,脚本在备份完后会调小)
mysql -u$DBUSER -p$DBPASSWORD --host= --socket=$sock --host=$host -BN -e "SET GLOBAL netwritetimeout=1800";
 
由于想要利用并发函数,将要使用的命令导入到${BACKUP_DIR}/cyt.log日志里,然后通过并发函数execConcurrency和数组dumpAllTable来实现本脚本的目的
本脚本可以实现多实例备份,如果多实例备份的用户名和密码不同,可以使用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以下版本如何实现并发备份”这篇文章的所有内容,感谢各位的阅读!

(编辑:92站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!