mysqldump5.7以下版本如何实现并发备份

67次阅读
没有评论

共计 4471 个字符,预计需要花费 12 分钟才能阅读完成。

这篇文章主要为大家展示了“mysqldump5.7 以下版本如何实现并发备份”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让丸趣 TV 小编带领大家一起研究并学习一下“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 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 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} # /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 以下版本如何实现并发备份”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注丸趣 TV 行业资讯频道!

正文完
 
丸趣
版权声明:本站原创文章,由 丸趣 2023-07-27发表,共计4471字。
转载说明:除特殊说明外本站除技术相关以外文章皆由网络搜集发布,转载请注明出处。
评论(没有评论)