本地MySQL数据库物理备份恢复解决方案
无论您在国内使用阿里云、腾讯云还是华为云,当您遇到数据备份恢复场景时,都会遇到需要使用Percona XtraBackup工具进行备份恢复的需求。
看着网上一大堆繁琐过时的备份和恢复解决方案,我不禁感到无聊。趁着再次帮助朋友们进行数据迁移的机会,整理并分享了之前的练习笔记,希望能够帮助到有需要的同学。
写的比较早
国内云平台从业者不多,成熟的解决方案也比较扎实,所以不难看出产品备份恢复策略甚至“御三家”的文档都很丰富“类似”。
- 阿里云:《RDS MySQL物理备份文件恢复到自建数据库》
- 腾讯云:《云数据库 MySQL - 使用物理备份恢复数据库》
- 华为云:《通过备份文件恢复到自建数据库(MySQL)》
本文将基于容器工具来处理数据恢复,避免不必要的软件依赖。容器时间由容器环境运营商负责,您不需要太担心系统配置的问题,我们直接使用Percona提供的官方镜像即可,以MySQL 5.7为例,大家可以根据自己的需要调整版本号。
# https://hub.docker.com/r/percona/percona-xtradb-cluster/
version: "3"
services:
percona:
image: percona/percona-xtradb-cluster:5.7
container_name: percona
restart: always
# 根据你的需要,声明暴露端口
# ports:
# - 3306:3306
environment:
- MYSQL_ALLOW_EMPTY_PASSWORD=1
volumes:
- ./node.cnf:/etc/mysql/node.cnf
- ./data:/var/lib/mysql:rw
- ./restore:/var/lib/mysql-files:rw
上面配置中,我声明了两个目录用于数据存储。第一个是存放云数据库备份的目录restore
,第二个是临时存储恢复的数据库文件的目录data
目录。将以上内容保存为docker-compose.yml
,稍后使用。
接下来编写一个可用于恢复的数据库配置文件:
[mysqld]
skip-grant-tables
ignore-db-dir=lost+found
datadir=/var/lib/mysql
socket=/tmp/mysql.sock
skip-host-cache
#coredumper
#server_id=0
binlog_format=ROW
default_storage_engine=InnoDB
innodb_flush_log_at_trx_commit = 0
innodb_flush_method = O_DIRECT
innodb_file_per_table = 1
innodb_autoinc_lock_mode=2
bind_address = 0.0.0.0
wsrep_slave_threads=2
wsrep_cluster_address=gcomm://
wsrep_provider=/usr/lib64/galera3/libgalera_smm.so
wsrep_cluster_name=noname
wsrep_node_address=172.20.12.2
wsrep_node_incoming_address=0cdb19fc56e4:3306
wsrep_sst_method=xtrabackup-v2
wsrep_sst_auth='xtrabackup:xtrabackup'
[client]
socket=/tmp/mysql.sock
[sst]
progress=/var/lib/mysql/sst_in_progresss
将上述配置保存为node.cnf
,然后与之前的eml-docker结合起来。 放置相同的目录并使用熟悉的docker-compose up -d
启动数据库实例进行数据恢复。
...
2021-10-12T06:08:37.329788Z 0 [Note] Server socket created on IP: '0.0.0.0'.
2021-10-12T06:08:37.385234Z 0 [Note] InnoDB: Buffer pool(s) load completed at 211012 6:08:37
2021-10-12T06:08:37.665867Z 0 [Note] mysqld: ready for connections.
Version: '5.7.33-36-57' socket: '/tmp/mysql.sock' port: 3306 Percona XtraDB Cluster (GPL), Release rel36, Revision a1ed9c3, WSREP version 31.49, wsrep_31.49
2021-10-12T06:08:37.666282Z 2 [Note] WSREP: Initialized wsrep sidno 2
...
使用 docker-compose log -f
显示运行日志。等待一段时间,当看到类似上面的日志,包括“ready to connect”时,就可以开始数据恢复操作了。
恢复数据
将需要恢复的数据复制到本地目录 准备好数据备份文件后,我们进入容器进行进一步的操作: 进入容器后,首先切换到工作目录: 假设我们的备份文件格式为 以tar 格式保存文件 解压备份文件后,我们就可以正式开始数据恢复操作了。 数据恢复时间取决于备份文件的大小。 当看到上面的日志输出时,说明正常MySQL实例正常运行的所有数据文件都已经准备好了。 但是,为了执行完整的数据导出,我们需要执行一些额外的操作。 在上述操作过程中,由于数据库实例要稳定运行,所以数据并不是直接恢复到restore
(对应目录/var/files/mysql-),也可以使用命令
需要先解压。如果涉及其他格式,例如docker cp
用于直接复制到容器中,但对于大文件来说不是很愉快。数据解压
docker exec -it percona bash
cd /var/lib/mysql-files/
。
。 tar zxvf *.tar
innobackupex --defaults-file=/etc/mysql/node.cnf --apply-log /var/lib/mysql-files/
InnoDB: 5.7.32 started; log sequence number 3006781461
xtrabackup: starting shutdown with innodb_fast_shutdown = 1
InnoDB: FTS optimize thread exiting.
InnoDB: Starting shutdown...
InnoDB: Shutdown completed; log sequence number 3006781480
211013 07:57:02 completed OK!
导出数据文件
/var/lib/mysql
目录下,而是解压到目录mysql-files
为了正确导出数据,我们需要允许数据库实例读取我们恢复的数据,所以我们用解压后的数据完全覆盖数据库实例数据。
cp -r /var/lib/mysql-files/* /var/lib/mysql/
rm -rf /var/lib/mysql-files/*
启动后,我们切换出容器并执行docker-compose down && docker-compose up -d
我们删除之前的容器并重新创建一个干净的新容器以继续数据恢复。使用 docker exec -it
重新进入容器:
docker exec -it percona bash
使用默认用户名进入 MySQL 交互终端:
mysql -u xtrabackup
尝试列出当前可以读取的数据库: 找到 MySQL在云端数据库已在本地正确恢复。
但是,如果您尝试使用mysqldump
直接导出数据,可能会出现“PXC”错误。
mysqldump: Got error: 1105: Percona-XtraDB-Cluster prohibits use of LOCK TABLE/FLUSH TABLE <table> WITH READ LOCK/FOR EXPORT with pxc_strict_mode = ENFORCING when using LOCK TABLES
要解决这个文件,我们需要在MySQL交互终端中进行全局设置:
mysql> set global pxc_strict_mode=DISABLED ;
Query OK, 0 rows affected (0.00 sec)
然后导出数据库就不会再有问题了:
mysqldump -u xtrabackup YOUR_DATABASE > backup.sql
由于我们导出的是标准数据库备份,所以继续迁移就是也很简单。您可以使用以下方法:
mysql -u USER -p DATABSE_NAME < backup.sql
或加载文件
来快速恢复和重建数据库。
最后
对于工程师来说,懒惰是一种美德,但偷懒的前提是能够正确、简单地发现并解决一个问题,并互相鼓励。
作者:苏洋
版权声明
本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。