Mysql_06_备份

一、使用 mysqldump 备份

1、docker 容器中的mysql备份

#!/bin/bash

#指定容器 id
container_name=c128cdfef408

# 指定备份目录,如果不存在,则创建

data_dir=/root/back/mysql8/xls_fs
if [ ! -d "$data_dir" ]; then
  mkdir -p $data_dir
fi

# 执行 docker 备份,注意,这里不需要添加 -it 参数,如果添加了在使用 crontab 定时执行的时候dump出来的文件大小始终是0,去掉-it就可以了,按照文档解释-t是分配一个伪终端,但是crontab执行的时候实际是不需要的
/usr/bin/docker exec  ${container_name} mysqldump -uroot -proot --databases xls_fs > "$data_dir/data_`date +%Y%m%d%H%M%S`.sql"

#删除 7 天前的备份
find $data_dir -type f -mtime +7 -exec rm {} \;

crontab -e 添加如下内容,每天早上 1点备份:

[root@localhost mysql8]# crontab -e
* 1 * * * /root/back/mysql8/xls_fs.sh

查看定时任务:

[root@localhost mysql8]# crontab -l
* 1 * * * /root/back/mysql8/xls_fs.sh

二、使用 XtraBackup 备份

2.1、介绍与安装

https://www.percona.com/doc/percona-xtrabackup/8.0/intro.html

XtraBackup 功能:

  • 创建热门InnoDB备份而不暂停数据库
  • 进行MySQL的增量备份
  • 将压缩的MySQL备份流式传输到另一台服务器
  • 在线运行MySQL服务器之间的表
  • 轻松创建新的MySQL复制从属服务器
  • 备份MySQL而不向服务器添加负载

下载地址:
https://www.percona.com/downloads/Percona-XtraBackup-LATEST/

安装:

[huangkai@instance-3knenqmy ~]$ wget https://www.percona.com/downloads/Percona-XtraBackup-LATEST/Percona-XtraBackup-8.0-7/binary/redhat/7/x86_64/percona-xtrabackup-80-8.0.7-1.el7.x86_64.rpm

[huangkai@instance-3knenqmy ~]$ yum localinstall percona-xtrabackup-80-8.0.7-1.el7.x86_64.rpm

2.2、 安装 mysql 并配置备份用户

docker 安装mysql,docker-compose 配置内容如下:

version: "3.7"
services:
  mysql8: 
    image: 172.16.0.4:8870/mysql:8.0.17
    container_name: mysql8
    ports:
      - "3306:3306"
    volumes: 
      - "/etc/localtime:/etc/localtime:ro"
      - "/etc/timezone:/etc/timezone:ro"
      - "/data/docker/mysql8.0.17/data/:/var/lib/mysql"
      - "/data/docker/mysql8.0.17/conf/:/etc/mysql/conf.d"
    restart: "always"
    environment: 
      #如果不指定密码,用户只能本机登陆,且root密码为空
      MYSQL_ALLOW_EMPTY_PASSWORD: 'true'
      #MYSQL_ROOT_PASSWORD: 'root'

启动 mysql :

[huangkai@localhost docker]$ docker-compose up -d mysql8

配置备份用户:

mysql> CREATE USER 'bkpuser'@'localhost' IDENTIFIED BY 's3cr%T';
mysql> GRANT BACKUP_ADMIN, PROCESS, RELOAD, LOCK TABLES, REPLICATION CLIENT ON *.* TO 'bkpuser'@'localhost';
mysql> GRANT SELECT ON performance_schema.log_status TO 'bkpuser'@'localhost';
mysql> FLUSH PRIVILEGES;

创建软链接(可选)

上面在docker 宿主机中安装了 xtraBackup 工具,但是这个功能在备份时需要指定 mysql 的datadir 或 mysql的配置文件,上面docker 中挂载的 mysql 的数据存储目录与宿主机中的不一样,docker容器中使用的 /var/lib/mysql 目录,而宿主机中使用的是 /data/docker/mysql8.0.16/data目录, 而 xtraBackup 在备份时会读取 mysql 的 data 目录,这里指定的是 docker 容器中的目录,即/var/lib/mysql ,有两种方式

  • docker 在挂载时的 mysql 存储目录与宿主机的一样,并在 mysql.conf 配置文件中指定 datadir所在的目录。
  • 如果不一样,可以将宿主机中使用软链接将docker容器中使用的目录(/var/lib/mysql)与 xtraBackup 读取宿主机的目录相关联。如ln -s /data/docker/mysql8.0.16/data /var/lib/mysql ,注意 /data/docker/mysql8.0.16/data 不能写成 /data/docker/mysql8.0.16/data/,最后加了 / 会导致创建的软连接多一层目录

2.3、全量备份脚本

[root@instance-3knenqmy mysql8]# vim /root/back/mysql8/full_back.sh

#!/bin/bash

# mysql  数据存放目录
MYSQL_DATA_DIR=/var/lib/mysql

# mysql 端口号
MYSQL_PORT=3707
# MYSQL 主机
MYSQL_HOST=172.17.0.1
#mysql 用户名
MYSQL_USER=root
# mysql 密码
MYSQL_PASSWORD=root
MY_CNF=/data/docker/mysql8.0.17/conf/mysql.cnf  #mysql的配置文件
#mysql 的连接信息
MYSQL_CMD="--host=$MYSQL_HOST --port=$MYSQL_PORT  --user=$MYSQL_USER --password=$MYSQL_PASSWORD"

#  全量备份目录
FULL_BACKUP_BASE_DIR=/root/back/mysql8/full

#全量备份目录 ,以时间分隔
FULL_DATA_DIR=$FULL_BACKUP_BASE_DIR/`date +%Y%m%d%H%M%S`

XTRABACKUP_FULL=/usr/bin/xtrabackup

# 定义错误方法
error()
{
  echo "$1" 1>&2
  exit 1
}

if [ ! -x $XTRABACKUP_FULL ]; then
  error "$XTRABACKUP_FULL 命令找不到"
fi

echo "$0: MySQL备份脚本,备份时间: `date +%F' '%T' '%w`"

# 创建全量备份目录
mkdir -p $FULL_DATA_DIR
# 执行备份
$XTRABACKUP_FULL --defaults-file=$MY_CNF --backup --use-memory=4G $MYSQL_CMD --target-dir=$FULL_DATA_DIR

#  -----------------------------------删除之前的备份-----------------------------------------------------
# 查询所有全量备份
back_list=(`find $FULL_BACKUP_BASE_DIR -mindepth 1 -maxdepth 1 -type d -printf "%P\n" | sort -n`)

#全量备份保存的个数
KEEP_FULL_BACKUP=2

size=`expr ${#back_list[*]} - $KEEP_FULL_BACKUP`

if [ $size -gt 0 ];then
  cd $FULL_BACKUP_BASE_DIR
  for((i=0;i<$size;i++)); do
    echo "delete backup :" ${back_list[i]}
    rm -rf ${back_list[i]}
  done
fi

将上面的增量备份添加到 crontab中,并以每5分钟执行一次

[root@instance-3knenqmy mysql8]# crontab -l
*/5 * * * * /root/back/mysql8/full_back.sh >/dev/null 2>&1
[root@instance-3knenqmy mysql8]#

2.4、增量备份脚本

[root@instance-3knenqmy mysql8]# vim /root/back/mysql8/incr_back.sh
#!/bin/bash

# mysql  数据存放目录
MYSQL_DATA_DIR=/var/lib/mysql
# mysql 端口号
MYSQL_PORT=3707
# MYSQL 主机
MYSQL_HOST=172.17.0.1
#mysql 用户名
MYSQL_USER=root
# mysql 密码
MYSQL_PASSWORD=root
MY_CNF=/data/docker/mysql8.0.17/conf/mysql.cnf  #mysql的配置文件
#mysql 的连接信息
MYSQL_CMD="--host=$MYSQL_HOST --port=$MYSQL_PORT  --user=$MYSQL_USER --password=$MYSQL_PASSWORD"

# 全量备份目录
FULL_BACKUP_BASE_DIR=/root/back/mysql8/full

# 增量备份目录
INCR_BACKUP_BASE_DIR=/root/back/mysql8/incr
INCR_DATA_DIR=$INCR_BACKUP_BASE_DIR/`date +%Y%m%d%H%M%S`

# 查询最新的增量备份
LATEST_FULL_BACKUP=`find $INCR_BACKUP_BASE_DIR -mindepth 1 -maxdepth 1 -type d -printf "%P\n" | sort -nr | head -1`
incremental_basedir=''
# 如果上次使用的增量备份存在
if [ -n "$LATEST_FULL_BACKUP" ]
then
  incremental_basedir=$INCR_BACKUP_BASE_DIR/$LATEST_FULL_BACKUP
  echo "查询使用上次增量备份: $LATEST_FULL_BACKUP"
else
   LATEST_FULL_BACKUP=`find $FULL_BACKUP_BASE_DIR -mindepth 1 -maxdepth 1 -type d -printf "%P\n" | sort -nr | head -1`
  incremental_basedir=$FULL_BACKUP_BASE_DIR/$LATEST_FULL_BACKUP
  echo "查询全量备份做为  incremental-basedir: $incremental_basedir"
fi

# 创建增量备份目录
mkdir -p $FULL_BACKUP_BASE_DIR
XTRABACKUP_FULL=/usr/bin/xtrabackup
$XTRABACKUP_FULL --backup --target-dir=$INCR_DATA_DIR $MYSQL_CMD --incremental-basedir=$incremental_basedir

# -----------------------删除之前的增量备份 ---------------------------------------
# 查询所有增量备份
back_list=(`find $INCR_BACKUP_BASE_DIR -mindepth 1 -maxdepth 1 -type d -printf "%P\n" | sort -n`)
#增量备份保存的个数
KEEP_FULL_BACKUP=2
size=`expr ${#back_list[*]} - $KEEP_FULL_BACKUP`
if [ $size -gt 0 ];then
  cd $INCR_BACKUP_BASE_DIR
  for((i=0;i<$size;i++)); do
    echo "delete backup :" ${back_list[i]}
    rm -rf ${back_list[i]}
  done
fi

2.5、数据恢复

查看备份目录结构

[root@instance-3knenqmy mysql8]# tree -L 2
.
├── full
│   └── 20190916155615
├── full_back.sh
├── incr
│   └── 20190916155653
├── incr_back.sh

执行恢复:

[root@instance-3knenqmy mysql8]# xtrabackup --prepare --apply-log-only --target-dir=/root/back/mysql8/full/20190916155615

[root@instance-3knenqmy mysql8]# xtrabackup --prepare --apply-log-only --target-dir=/root/back/mysql8/full/20190916155615 --incremental-dir=/root/back/mysql8/incr/20190916155653

[root@instance-3knenqmy mysql8]# cd /data/docker
[root@instance-3knenqmy docker]# docker-compose stop mysql8 #停止 mysql

[root@instance-3knenqmy docker]# rm -rf mysql8.0.17/data/* #删除mysql data 目录下所有文件
[root@instance-3knenqmy docker]# ll mysql8.0.17/data/
[root@instance-3knenqmy docker]# cd -
/root/back/mysql8
[root@instance-3knenqmy mysql8]# xtrabackup --copy-back --target-dir=/root/back/mysql8/full/20190916155615
[root@instance-3knenqmy docker]# cd -
[root@instance-3knenqmy docker]# ll mysql8.0.17/data/ # 可以查看 mysql 数据已恢复
[root@instance-3knenqmy docker]# chown polkitd:input mysql8.0.17/data/ -R # 授权
[root@instance-3knenqmy docker]# docker-compose restart mysql8 #重启 mysql ,数据已恢复

2.6、数据恢复思考

一般在企业中,全量备份可以每周一次,增量备份每天一次,比如每天凌晨2点进行增量备份,而恰巧第二天中午12点数据库崩溃了,则从凌晨2点到第二天中午12点的这段时间内是没有进行数据备份的,怎么才能将这些时间内的数据也恢复呢???
此时,可以使用 mysql 中的 binlog 进行恢复,
查看文档: https://www.cnblogs.com/jian0110/p/9404773.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hellowordx007

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值