一、前提
某項目外網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

