11

MySQL 云数据库物理备份本地恢复方案

 3 years ago
source link: https://soulteary.com/2021/10/13/mysql-cloud-database-physical-backup-local-recovery-solution.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

在国内不论是使用阿里云、腾讯云还是华为云的云平台版本的 MySQL 数据库,在遇到数据备份恢复的场景,都会遇到需要使用 Percona XtraBackup 工具进行备份还原的需求。

看着网上一堆既啰嗦又落后的备份恢复方案,不免厌烦,借着再次帮朋友做数据迁移的机会,整理分享之前的实战笔记,希望能够帮助到有需求的同学。

国内云平台从业者不多,加上成熟的方案相对固定,所以我们不难看到“御三家”的产品备份恢复策略甚至文档都非常“相似”。

本文将基于容器工具的方式进行数据恢复处理,避免折腾不必要的软件依赖。

编写数据库恢复实例配置文件

容器时代,如果你不是容器环境的运维工作者,不必过度纠结系统配置,我们直接使用 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,然后和之前的 docker-compose.yml 放置相同目录,使用我们熟悉的 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 logs -f 查看运行日志,稍等片刻,看到类似上面的日志,包含 “ready for connections” 就可以开始进行数据恢复操作啦。

进行数据恢复

将你需要恢复的数据复制到本地的 restore目录中(对应容器内 /var/lib/mysql-files/ 目录),也可以使用 docker cp 命令直接向容器复制,不过对于大文件来说,体验并不友好。

数据“解压缩”

在准备好数据备份文件之后,我们进入容器进行后续操作:

docker exec -it percona bash

进入容器之后,先切换工作目录:

cd /var/lib/mysql-files/

假设我们的备份文件格式为 tar 格式的存储文件,需要先进行解压缩。如果是其他格式,比如 .xb 格式,容器内置了 qpressxbstream 工具,参考你的云平台提供的说明文档直接使用就是了。

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!

当你看到上面的日志输出后,正常的 MySQL 实例正常运行的数据文件就都就绪了。

但是为了进行完整数据导出,我们还需要进行一些额外操作。

导出数据文件

在上文的操作过程中,考虑数据库实例需要稳定运行,所以并没有直接将数据恢复到 /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> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| YOUR_DATABASE      |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
5 rows in set (0.01 sec)

会发现云端的 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

或者 file load 的方式快速进行数据库恢复重建。

对于工程师而言,懒惰是美德,但是懒惰成立的前提是你能够正确的、简单的定位和解决问题,共勉。


Recommend

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK