共计 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 行业资讯频道!