0
点赞
收藏
分享

微信扫一扫

手动构建percona-xtrabackup Docker镜像,并实现mysql数据备份

Brose 2021-09-29 阅读 59
日记本

由于最近项目比较多,并且都需要自己部署运维Mysql,为了保证mysql数据的安全,那么数据备份就必不可少了。之前做mysql数据备份的时候,都是使用的xtrabackup,所以这次也不例外,由于需要备份的mysql服务器较多,每台都安装一遍xtrabackup的话,重复工作量就太大了,这时候,当然就想着将xtrabackup容器化,需要使用的地方,只需要拉取一下镜像,启动一下容器,感觉一下子就简单起来了呢。

不想动手的小伙伴,可以拉取我已经封装好的镜像,该镜像仅在mysql 5.7测试,mysql 8不支持,5.6是否可用,就各位自己测试啦

docker pull f763180872/xtrabackup

docker run -d --name mysql_backup --privileged \
    -e BASE_DIR=/mnt/backup \
    -e OPTION="-H127.0.0.1 -P3306 -uroot -ppasswd" \
    -v /var/lib/mysql/data:/var/lib/mysql \
    -v /mnt:/mnt \
    --restart=always \
    --net=host
    f763180872/xtrabackup

参数说明:
BASE_DIR: 备份文件存放目录
OPTION: mysql连接参数-H IP地址 -P 端口号 -u 用户名 -p 密码

手动开始折腾

1. 准备需要的文件

点击下载xtrabackup
全量备份脚本fullbak.sh
#!/bin/bash
echo "export HAS_FALL_BACK=" > /.backTemp

# docker需要判断环境变量文件是否存在
if [ -f /dockerenv ];then
  source /dockerenv
  env
fi

INNOBACKUPEXFULL=/usr/bin/innobackupex
TODAY=`date +%Y%m%d%H%M`
YESTERDAY=`date -d"yesterday" +%Y%m%d%H%M`
FULLBACKUPDIR=$BASE_DIR/full # 全库备份的目录
INCRBACKUPDIR=$BASE_DIR/incr # 增量备份的目录
TMPFILEDIR=$BASE_DIR/logs # 日志目录
TMPFILE="$TMPFILEDIR/innobackup_$TODAY.$$.log" # 日志文件

#############################################################################
# 打印错误信息并退出
#############################################################################
error()
{
    echo "$1" 1>&2
    exit 1
}
 
# 开始备份前检查相关的参数
if [ ! -x $INNOBACKUPEXFULL ]; then
  error "$INNOBACKUPEXFULL does not exist."
fi
 
#if [ ! -d $BASE_DIR ]; then
#  error "Backup destination folder: $BASE_DIR does not exist."
#fi
 
# 输出备份信息
echo "----------------------------"
echo
echo "$0: MySQL backup script"
echo "started: `date '+%Y-%m-%d %H:%M:%S'`"
echo
 
# 如果备份目录不存在则创建相应的全备增备目录
for i in $FULLBACKUPDIR $INCRBACKUPDIR $TMPFILEDIR; do
  if [ ! -d $i ]; then
    mkdir -pv $i
  fi
done
 
# 压缩上传前一天的备份
echo "压缩前一天的备份"
cd $BASE_DIR
tar -zcf $YESTERDAY.tar.gz ./full/ ./incr/
# scp -P 8022 $YESTERDAY.tar.gz root@192.168.10.46:/data/backup/mysql/
#if [ $? = 0 ]; then
rm -rf $FULLBACKUPDIR $INCRBACKUPDIR
echo "开始全量备份"
echo "start exec $INNOBACKUPEXFULL $OPTION $FULLBACKUPDIR > $TMPFILE 2>&1"
$INNOBACKUPEXFULL $OPTION $FULLBACKUPDIR > $TMPFILE 2>&1
#else
#  echo "远程备份失败"
#fi
 
if [ -z "`tail -1 $TMPFILE | grep 'completed OK!'`" ] ; then
 echo "$INNOBACKUPEXFULL failed:"; echo
 echo "---------- ERROR OUTPUT from $INNOBACKUPEXFULL ----------"
# cat $TMPFILE
# rm -f $TMPFILE
 exit 1
fi

# 这里获取这次备份的目录 
THISBACKUP=`awk -- "/Backup created in directory/ { split( \\\$0, p, \"'\" ) ; print p[2] }" $TMPFILE`
echo "THISBACKUP=$THISBACKUP"
#rm -f $TMPFILE
echo "Databases backed up successfully to: $THISBACKUP"

# Cleanup
echo "delete tar files of 10 days ago"
find $BASE_DIR/ -mtime +10 -name "*.tar.gz"  -exec rm -rf {} \;
 
echo
echo "completed: `date '+%Y-%m-%d %H:%M:%S'`"
echo "export HAS_FALL_BACK=true" > /.backTemp
exit 0
增量备份脚本incrbak.sh
#!/bin/bash
if [ -f /.backTemp ];then
  source /.backTemp
fi

if [ ! -d $HAS_FALL_BACK ]; then
  echo "未全量备份,跳过本次增量备份"
  exit 0
fi

# docker需要判断环境变量文件是否存在
if [ -f /dockerenv ];then
  source /dockerenv
  env
fi

INNOBACKUPEXFULL=/usr/bin/innobackupex
TODAY=`date +%Y%m%d%H%M`
YESTERDAY=`date -d"yesterday" +%Y%m%d%H%M`
FULLBACKUPDIR=$BASE_DIR/full # 全库备份的目录
INCRBACKUPDIR=$BASE_DIR/incr # 增量备份的目录
TMPFILEDIR=$BASE_DIR/logs # 日志目录
TMPFILE="$TMPFILEDIR/innobackup_$TODAY.$$.log" # 日志文件

#############################################################################
# 打印错误信息并退出
#############################################################################
error()
{
    echo "$1" 1>&2
    exit 1
}
 
# 开始备份前检查相关的参数
if [ ! -x $INNOBACKUPEXFULL ]; then
  error "$INNOBACKUPEXFULL does not exist."
fi
 
#if [ ! -d $BASE_DIR ]; then
#  error "Backup destination folder: $BASE_DIR does not exist."
#fi
 
# 输出备份信息
echo "----------------------------"
echo
echo "$0: MySQL backup script"
echo "started: `date '+%Y-%m-%d %H:%M:%S'`"
echo "exec $INNOBACKUPEXFULL $OPTION $FULLBACKUPDIR > $TMPFILE 2>&1"
echo
 
# 如果备份目录不存在则创建相应的全备增备目录
for i in $FULLBACKUPDIR $INCRBACKUPDIR $TMPFILEDIR; do
  if [ ! -d $i ]; then
    mkdir -pv $i
  fi
done
 
# 查找最近的全备目录
LATEST_FULL=`find $FULLBACKUPDIR -mindepth 1 -maxdepth 1 -type d -printf "%P\n"`
echo "最近的全备目录为: $LATEST_FULL" 

# 如果最近的全备仍然可用执行增量备份
# 创建增量备份的目录
TMPINCRDIR=$INCRBACKUPDIR/$LATEST_FULL
mkdir -p $TMPINCRDIR
BACKTYPE="incr"
# 获取最近的增量备份目录
LATEST_INCR=`find $TMPINCRDIR -mindepth 1 -maxdepth 1 -type d | sort -nr | head -1`
echo "最近的增量备份目录为: $LATEST_INCR"
# 如果是首次增量备份,那么basedir则选择全备目录,否则选择最近一次的增量备份目录
if [ ! $LATEST_INCR ] ; then
  INCRBASEDIR=$FULLBACKUPDIR/$LATEST_FULL
else
  INCRBASEDIR=$LATEST_INCR
fi
echo "Running new incremental backup using $INCRBASEDIR as base."
echo "start exec $INNOBACKUPEXFULL $OPTION --incremental $TMPINCRDIR --incremental-basedir $INCRBASEDIR > $TMPFILE 2>&1"
$INNOBACKUPEXFULL $OPTION --incremental $TMPINCRDIR --incremental-basedir $INCRBASEDIR > $TMPFILE 2>&1

 
if [ -z "`tail -1 $TMPFILE | grep 'completed OK!'`" ] ; then
 echo "$INNOBACKUPEX failed:"; echo
 echo "---------- ERROR OUTPUT from $INNOBACKUPEX ----------"
 exit 1
fi

# 这里获取这次备份的目录 
THISBACKUP=`awk -- "/Backup created in directory/ { split( \\\$0, p, \"'\" ) ; print p[2] }" $TMPFILE`
echo "THISBACKUP=$THISBACKUP"
echo
echo "Databases backed up successfully to: $THISBACKUP"

echo
echo "incremental completed: `date '+%Y-%m-%d %H:%M:%S'`"
exit 0
镜像依赖安装脚本install.sh
#!/bin/bash
apt update -y
dpkg -i /root/percona-xtrabackup-24_2.4.21-1.focal_amd64.deb
apt install -fy
apt install cron -y
rm -rf /root/percona-xtrabackup-24_2.4.21-1.focal_amd64.deb
apt clean
镜像启动脚本init.sh
#!/bin/bash
# 如果用户未设置BASE_DIR,备份会保存在VOLUME中,防止备份丢失
if [ ! -d $BASE_DIR ]; then
  export BASE_DIR=/data
fi

# 将环境变量写入到文件中,方便定时任务在执行时获取,要不定时任务获取不到Docker设置的环境变量
echo "export BASE_DIR='$BASE_DIR'" > /dockerenv
echo "export OPTION='$OPTION'" >> /dockerenv
if [ "$1" == "init" ];then
    # 初始化执行环境
    /etc/init.d/cron start
    echo '0 3 * * 3,6 root /root/fullbak.sh > /var/log/mysql_backup.log 2>&1' >> /etc/crontab
    echo '0 */2 * * * root /root/incrbak.sh >> /var/log/mysql_backup.log 2>&1' >> /etc/crontab
    /root/fullbak.sh > /var/log/mysql_backup.log 2>&1
    tail -f /dev/null
else
    # 透传待执行的命令
    exec "$@"
fi
Dockerfile
FROM ubuntu:20.04

USER root
ENV LANG=C.UTF-8

COPY percona-xtrabackup-24_2.4.21-1.focal_amd64.deb fullbak.sh incrbak.sh install.sh /root/

RUN sh /root/install.sh && rm -rf /root/install.sh && chmod a+x /root/*.sh

COPY init.sh /root/
RUN chmod a+x /root/*.sh

VOLUME /data
ENTRYPOINT ["/root/init.sh"]

CMD [ "init" ]

2. 构建镜像

把上面所有的文件准备好之后放在同一个目录下
执行构建命令即可

docker build -t name .

以后要使用的话,就只需要拉取一下镜像,再将镜像运行起来,也就OK了

举报

相关推荐

0 条评论