一、前提
某项目外网Mysql的全量备份数据(xtrabackup导出的备份),因项目需要,需要博主本地进行还原,在这次还原的过程中,遇到的坑很多,特开此贴记录下。
二、环境
系统版本:CentOS Linux release 7.4.1708 (Core)
Mysql版本:5.7.26
Xtrabackup版本: 2.4.24
Docker版本: 1.13.1
三、架构
(1)宿主机 一台
(2)Mysql容器 单节点
(3)Xtrabackup容器 单节点
四、容器部署注意点:
Mysql容器运行时,需要将数据目录(/var/lib/mysql)、配置文件(my.cnf)挂载到宿主机的目录上,并且Xtrabackup容器也做相同的目录挂载,这样就等于在宿主机上直接操作数据的备份与还原。
五、操作步骤
5.1 宿主机新建Mysql相关文件夹、文件
博主习惯在home目录操作,因此接下来的所有新建文件夹、文件都放在/home目录下。
cd /home mkdir Mysql5.7.26
接着在Mysql5.7.26目录下建立docker文件夹,用于存放Mysql使用的配置文件(mysqld.cnf)和启动脚本(run.sh)
目录展示如下图:
mysqld.cnf具体内容如下:
[mysqld]
user=mysql
character-set-server=utf8
default_authentication_plugin=mysql_native_password
secure_file_priv=/var/lib/mysql
expire_logs_days=7
sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
max_connections=1000
socket=/var/lib/mysql/mysql.sock
datadir=/var/lib/mysql
# xtrabackup导出的备份中会有一个文件叫backup-my.cnf,需要将其中的配置拷贝过来,有些变量可能会导致Mysql无法启动,需要根据实际情况删除变量。
innodb_checksum_algorithm=crc32
innodb_data_file_path=ibdata1:1G:autoextend
innodb_log_files_in_group=2
innodb_log_file_size=2147483648
innodb_page_size=16384
# undo文件所在的目录,要根据实际情况调整。
innodb_undo_directory=/var/lib/mysql
# undo文件要根据备份中的数量来调整,博主的备份数据中存在95个undo文件。
innodb_undo_tablespaces=95
# 忽略权限管理,任何人都可以连接,这样做的原因是备份是其他人提供的外网数据,不方便提供账号密码,避免还原后无法连接数据库。
skip-grant-tables
[client]
default-character-set=utf8
socket=/var/lib/mysql/mysql.sock
[mysql]
default-character-set=utf8
socket=/var/lib/mysql/mysql.sock
mysqld.cnf中加了注释的配置都是踩过的坑,需要特别注意。
run.sh脚本内容:
#!/bin/bash docker run --name mysql5.7.26 \ --network=host \ -p 3306:3306 \ -v /home/Mysql5.7.26/docker/mysqld.cnf:/etc/mysql/my.cnf \ -v /home/Mysql5.7.26/data:/var/lib/mysql \ -v /home/Mysql5.7.26/log:/var/log/mysql \ -e MYSQL_ROOT_PASSWORD=mysql.2018 \ -e TZ=America/Los_Angeles \ -d mysql:5.7.26
时区根据实际情况调整,博主这边的数据是西八区的,所以时区特意设成洛杉矶。
最重要的是目录、文件的挂载:
-v /home/Mysql5.7.26/docker/mysqld.cnf:/etc/mysql/my.cnf # 表示将配置文件挂载到容器中,这样方便我们随时调整Mysql的配置,然后重启生效。
-v /home/Mysql5.7.26/data:/var/lib/mysql # 表示将Mysql最重要的数据目录挂载到宿主机的data目录
挂载的宿主机目录如果不存在,会自动创建,创建后展示如下:
5.2 启动Mysql
运行run.sh脚本即可
查看日志,看下是否正常启动:
docker logs -f mysql5.7.26
只要没有error级别的日志就是成功了。
mkdir /home/xtrabackup 新建xtrabackup目录

新建dockerfile文件,内容如下:
FROM centos:7.4.1708 ADD percona-xtrabackup-24-2.4.24-1.el7.x86_64.rpm / RUN yum install -y /percona-xtrabackup-24-2.4.24-1.el7.x86_64.rpm && \ yum clean all && \ rm -rf /percona-xtrabackup-24-2.4.24-1.el7.x86_64.rpm

cd /home/xtrabackup/ docker build -t xtrabackup:v1 .
docker run -it -d \ --name xtrabackup \ --network=host \ -e TZ=America/Los_Angeles \ -v /home/backup:/backup \ -v /home/data:/data \ -v /home/Mysql5.7.26/docker/mysqld.cnf:/etc/mysql/my.cnf \ -v /home/Mysql5.7.26/data:/var/lib/mysql \ -v /home/Mysql5.7.26/log:/var/log/mysql \ xtrabackup:v1
可以看到,时区要和Mysql容器保持一致;
Mysql容器挂载的三个地址也要保持一致,因为xtrabackup的备份、还原操作都是依赖于Mysql的配置和数据的。
并且新增了两个挂载地址,
-v /home/backup:/backup # 表示备份数据的存放位置
-v /home/data:/data # 讲道理这个目录我没有用到过,忘记干啥的了
执行docker ps,查看启动情况,可以看到都正常的运行中。
5.6 还原全量备份数据
文章最开始有提到,博主的目的是还原数据,手上已经有备份数据了,将备份的数据拷贝到宿主机的/home/backup中,如下图:
因为我们上面将/home/backup目录挂载到了xtrabackup容器的/backup目录,因此当我们拷贝数据后,容器中的/backup目录也会有相应的数据内容。
我们可以进入xtrabackup容器进行查看:
docker exec -it xtrabackup /bin/bash cd /backup ll
可以看到容器中有备份数据了。
接下来,我们要开始还原数据,
1)先停止Mysql容器
docker stop mysql5.7.26
2)删除宿主机中Mysql数据的目录内容(即/home/Mysql5.7.26/data目录)
cd /home/Mysql5.7.26 rm -rf data/*
3)进入xtrabackup容器
docker exec -it xtrabackup /bin/bash
4)执行保证数据完整性命令(apply-log)
innobackupex --defaults-file=/etc/mysql/my.cnf --user=root --password=mysql.2018 --apply-log /backup/mysql/20210928/3306/FULL/

innobackupex --defaults-file=/etc/mysql/my.cnf --user=root --password=mysql.2018 --copy-back /backup/mysql/20210928/3306/FULL/
除了--copy-back命令外,其他的内容和apply-log命令一样。
博主执行过程中遇到了下图报错:
原因是容器中的/var/lib/mysql目录权限被改了,应该是apply-log执行后导致的,
修复方式是:
退出容器
exit
重启xtrabackup容器
docker restart xtrabackup
再次进入容器
docker exec -it xtrabackup /bin/bash
重新执行--copy-back命令即可。
innobackupex --defaults-file=/etc/mysql/my.cnf --user=root --password=mysql.2018 --copy-back /backup/mysql/20210928/3306/FULL/
执行成功,如下图:
docker start mysql5.7.26
docker logs -f mysql5.7.26

rm -rf /home/Mysql5.7.26/data/ib_logfile0 rm -rf /home/Mysql5.7.26/data/ib_logfile1
docker restart mysql5.7.26

