千家信息网

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

发表于:2024-10-04 作者:千家信息网编辑
千家信息网最后更新 2024年10月04日,这篇文章主要为大家展示了"mysqldump5.7以下版本如何实现并发备份",内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下"mysqldump5.7以下版本如
千家信息网最后更新 2024年10月04日mysqldump5.7以下版本如何实现并发备份

这篇文章主要为大家展示了"mysqldump5.7以下版本如何实现并发备份",内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下"mysqldump5.7以下版本如何实现并发备份"这篇文章吧。

mysqldump5.7以下版本多线程备份单表

【背景说明】

mysqldump适用于备份单表,或者数量级较小的库的备份。一般情况下innobackupex备份数量级大的库,速度是很快的。但是其瓶颈在于如果业务需要多实例部分对象迁移到新的实例里,此时就无法满足该情况。(mysqldumper在此不做讨论)。

下面简单列举mysqldump适用的场景:

  • 备份多个单表

  • 备份一个或多个库

  • 备份存储过程、自定义函数或事件

  • 只备份数据不备份表结构

  • 只备份表结构不备份数据

  • 其他

mysqldump虽然使用起来比较灵活,但是它无法实现并发备份,故本文描述的就是实现如何用mysqldump实现并发备份

【思路说明】

把需要备份的一个库或多个库,提取这些库下面所有的表进行一个个备份:这样可以利用脚本进行多线程备份这些单表,从而实现库级的并发备份

【具体脚本】

点击(此处)折叠或打开

  1. #!/bin/bash

  2. #注释:mysqldump多线程备份多表

  3. #Auther:cyt

  4. #date:2016-06-23

  5. #按照多实例循环框架

  6. function instance()

  7. {

  8. 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}'`

  9. do

  10. ##避免循环的port和sock不匹配

  11. 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}'`

  12. #由于该脚本是并行备份,以防由于繁忙,导致获取不到dump连接,故将该参数调大(备份完后会调小)

  13. mysql -u$DB_USER -p$DB_PASSWORD --host= --socket=$sock --host=$host -BN -e "SET GLOBAL net_write_timeout=1800";

  14. #调用输出备份命令的日志函数

  15. log

  16. echo "-----端口号为"$port"的mysql实例开始按表并发备份:开始时间为"`date "+%Y-%m-%d %H:%M:%S"`

  17. #调用备份函数

  18. dumpAllTable

  19. #计算备份所用时间

  20. END=`date "+%Y-%m-%d %H:%M:%S"`

  21. END_T=`date -d "$END" +%s`

  22. TIME_INVENTAL_M=$[($END_T-$BEGIN_T)/60]

  23. TIME_INVENTAL_S=$[($END_T-$BEGIN_T)%60]

  24. echo '-----端口号为'$port'的mysql实例于' $END '备份完成,使用时间为 '$TIME_INVENTAL_M'分钟'$TIME_INVENTAL_S'秒'

  25. #调用tardump函数,对备份文件进行压缩,注意本次压缩会删掉原文件

  26. tardump

  27. #将参数改为默认,以防耗尽内存

  28. mysql -u$DB_USER -p$DB_PASSWORD --host= --socket=$sock --host=$host -BN -e "SET GLOBAL net_write_timeout=60";

  29. done

  30. }




  31. #将要备份的单表从大到小输出到日志里面

  32. function log()

  33. {

  34. BACKUP_DIR=/data/backup/$DATE/$port;

  35. mkdir -p $BACKUP_DIR

  36. #过滤掉MySQL自带的DB

  37. if [ -e ${BACKUP_DIR}/cyt.log ];

  38. then rm -rf ${BACKUP_DIR}/cyt.log;

  39. fi;

  40. 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 `

  41. do

  42. mkdir -p ${BACKUP_DIR}/${a}

  43. 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;"`

  44. do

  45. 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;

  46. done

  47. done

  48. }




  49. #调用函数log,查看log日志调用并发函数实现多线程备份

  50. function dumpAllTable()

  51. {

  52. local schemaFile="${BACKUP_DIR}/cyt.log"

  53. #最大的表先备份(因多进程并发,最短完成时间依赖于最大表的完成)

  54. allTable=`cat $schemaFile | wc -l`

  55. i_import=0

  56. declare -a array_cmds

  57. i_array=0

  58. while read file; do

  59. i_import=`expr $i + 1`

  60. array_cmds[i_array]="${file}"

  61. i_array=`expr ${i_array} + 1`

  62. done < ${BACKUP_DIR}/cyt.log

  63. execConcurrency "${threadsNum}" "${array_cmds[@]}"

  64. }






  65. #并发函数

  66. function execConcurrency()

  67. {

  68. #并发数据量

  69. local thread=$1

  70. #并发命令

  71. local cmd=$2

  72. #定义管道,用于控制并发线程

  73. tmp_fifofile="/tmp/$$.fifo"

  74. mkfifo $tmp_fifofile

  75. #输入输出重定向到文件描述符6

  76. exec 6<>$tmp_fifofile

  77. rm -f $tmp_fifofile

  78. #向管道压入指定数据的空格

  79. for ((i=0;i<$thread;i++)); do

  80. echo

  81. done >&6

  82. #遍历命令列表

  83. while [ "$cmd" ]; do

  84. #从管道取出一个空格(如无空格则阻塞,达到控制并发的目的)

  85. read -u6

  86. #命令执行完后压回一个空格

  87. { eval $2;echo >&6; } & #> /dev/null 2>&1 &

  88. shift

  89. cmd=$2

  90. done

  91. #等待所有的后台子进程结束

  92. wait

  93. #关闭df6

  94. exec 6>&-

  95. }


  96. #压缩备份文件

  97. function tardump()

  98. {

  99. #使用tar压缩

  100. if [ -d ${BACKUP_DIR} ] && [ -n ${port} ]

  101. then

  102. echo "-----开始进行压缩端口号为"$port"的mysql实例的备份:开始时间"`date "+%Y-%m-%d %H:%M:%S"`

  103. cd $BACKUP_DIR;

  104. for b in `find $BACKUP_DIR -maxdepth 1 -type d ! -iname "${port}*" ! -iname '*.sql' ! -iname '*tar.gz' `

  105. do

  106. c=`basename $b`

  107. tar -zcvf $c'_'$(date +%F_%H-%M).tar.gz $c --remove-files > /dev/null

  108. done

  109. else echo "没有可以进行压缩的文件";

  110. fi;

  111. echo "-----压缩端口号为"$port"的mysql实例的备份文件:结束时间"`date "+%Y-%m-%d %H:%M:%S"`

  112. }


  113. #主函数

  114. function main()

  115. {

  116. #获取本地IP地址

  117. host=`ifconfig | grep 'inet addr:' | grep -v '127.0.0.1' | cut -d: -f2 | awk '{ print $1}'`

  118. DATE=`date +%F`

  119. #本次备份mysqldump --host --socket如果是本地用户备份,建议去掉host;(多实例本地用户密码问题需注意)

  120. #数据库用户

  121. DB_USER='cyt'

  122. #数据库用户对应的密码

  123. DB_PASSWORD='cyt'

  124. #记录开始的时间

  125. BEGIN=`date "+%Y-%m-%d %H:%M:%S"`

  126. BEGIN_T=`date -d "$BEGIN" +%s`

  127. echo '--------------开始按表并发备份:开始时间为 '$BEGIN

  128. #设置并发备份的线程数

  129. threadsNum=10

  130. #调用instance函数

  131. instance

  132. echo '--------------backup all database successfully!!!结束时间:' `date "+%Y-%m-%d %H:%M:%S"`

  133. }


  134. 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命令,下面是简单举例

    点击(此处)折叠或打开



    1. if [ $port -eq 3306 ]; then

    2. case $IP in

    3. '10.240.5.11')

    4. DB_USER='CYT1'

    5. DB_PASSWORD='1'

    6. ;;

    7. '10.240.5.12')

    8. DB_USER='CYT2'

    9. DB_PASSWORD='2'

    10. ;;

    11. '10.240.5.13')

    12. DB_PASSWORD='3'

    13. ;;

    14. esac

    15. else

    16. DB_PASSWORD='4'

    17. fi

以上是"mysqldump5.7以下版本如何实现并发备份"这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注行业资讯频道!

0