需求:
数据库A存在app1数据库,需要通过xtrabackup将此数据库迁移到数据库B,数据库B已经存在其他数据库数据库,要求传输过程不能对B数据库的数据造成损失。
根据需求,我将采用“传输表空间”(Transportable Tablespaces)的方式来完成这个任务,这是实现部分恢复(Partial Restore)最安全、最高效的方法。
本次测试数据库版本为MySQL 5.7
重要:准备工作与前提条件
在开始之前,请务必确认以下几点,否则恢复过程会失败:
- 备份与演练:在对生产环境进行任何操作之前,强烈建议在一个测试环境中完整演练一遍。同时,请确保服务器B已有完整的、可用的备份。
- XtraBackup 版本:确保在服务器A(或任何可以访问A数据库的机器)上安装了 Percona XtraBackup 2.4 版本。
- MySQL 用户权限:准备一个在服务器A和B上都拥有足够权限的MySQL用户(例如 RELOAD, PROCESS, LOCK TABLES, REPLICATION CLIENT 等),或者直接使用 root 用户。
- 磁盘空间:确保备份目录、服务器B的临时目录和最终数据目录都有足够的磁盘空间。
- innodb_file_per_table:这是最关键的前提条件。app1 数据库中所有需要恢复的 InnoDB 表都必须是独立表空间。请在服务器A和B上都执行以下SQL查询进行检查:
- SHOW VARIABLES LIKE 'innodb_file_per_table';
复制代码 必须确保其值为 ON。如果A服务器上此值为 OFF,XtraBackup 无法进行表级别的导出/导入。如果B服务器上此值为 OFF,则无法导入表空间。对于MySQL 5.7,该值通常默认为 ON。
操作流程
整个过程分为四个主要阶段:备份 (A) -> 准备 (A) -> 传输 -> 恢复 (B)
阶段一:在服务器 A 上执行部分备份
此步骤只备份 app1 数据库。
- 登录到服务器A。
- 创建一个用于存放备份的目录,例如:
- mkdir -p /data/backups/app1
复制代码 - 执行备份命令。--databases 参数是关键,它告诉 XtraBackup 只备份指定的数据库。
- xtrabackup --backup \
- --target-dir=/data/backups/app1 \
- --user=your_user \
- --password=your_password \
- --databases="app1"
复制代码
- --target-dir: 指定备份文件的存放路径。
- --user / --password: 你的MySQL用户名和密码。
- --databases="app1": 核心参数,指定只备份 app1 数据库。如果要备份多个,可以用空格隔开,如 "db1 db2"。
操作完成后,/data/backups/app1 目录下会包含 app1 数据库的数据文件和备份元数据。
阶段二:准备备份以供导出
这个“准备”步骤非常关键。我们需要使用 --export 选项,它会为每个 InnoDB 表生成一个 .cfg 元数据文件,这是在服务器B上导入表空间所必需的。
- 在服务器A上,对刚刚创建的备份执行 "prepare" 操作:
- xtrabackup --prepare --export \
- --target-dir=/data/backups/app1
复制代码
- --prepare: 应用事务日志,使数据文件达到一致状态。
- --export: 核心参数,为传输表空间做准备,生成 .exp 和 .cfg 文件。
- 操作完成后,你可以检查备份目录下的 app1 子目录,会看到每个表都有 .ibd, .cfg 文件。
阶段三:将备份文件传输到服务器 B
将准备好的备份目录从服务器A安全地复制到服务器B。
- 使用 scp 或 rsync 命令进行传输。rsync 更优,支持断点续传。
- # 在服务器A上执行
- rsync -avzP /data/backups/app1/ your_user@<服务器B的IP>:/data/restore/
复制代码
- 这会将 app1 目录完整地复制到服务器B的 /data/restore/ 目录下。
阶段四:在服务器 B 上恢复数据库
这是最精细操作的阶段,我们将一步步地将 app1 数据库导入到服务器B中,而完全不影响B上现有的其他数据库。
- 在服务器B上创建空的 app1 数据库,编码需要自定义,这里进行了简化。
登录服务器B的MySQL: - 在服务器B上为 app1 创建表结构。
我们需要先创建表的“空壳”(即表结构),然后才能导入数据。最简单的方法是从服务器A导出纯表结构。
- 在服务器A上执行:
- mysqldump --no-data --routines --triggers --events \
- -u your_user -p your_password app1 > /tmp/app1_schema.sql
复制代码 - 将 app1_schema.sql 文件从服务器A复制到服务器B。
- 在服务器B上导入表结构:
- mysql -u your_user -p your_password app1 < /path/to/app1_schema.sql
复制代码 现在,服务器B上有了一个名为 app1 的数据库,里面包含了所有表,但这些表都是空的。
- 解绑表空间(Discard Tablespace)。
对于 app1 数据库中的每一张表,我们需要先解除它与当前空 .ibd 文件的关联,为导入做准备。
- 登录服务器B的MySQL,并对每一张表执行:
- ALTER TABLE app1.your_table_name DISCARD TABLESPACE;
复制代码 - 如果表很多,可以运行以下SQL生成所有命令,然后复制执行:
- SELECT CONCAT('ALTER TABLE ', table_schema, '.', table_name, ' DISCARD TABLESPACE;')
- FROM information_schema.tables
- WHERE table_schema = 'app1';
复制代码
- 复制数据文件 (.ibd) 和元数据文件 (.cfg)。
- 首先,找到服务器B的MySQL数据目录(datadir):
- SHOW VARIABLES LIKE 'datadir';
复制代码 通常是 /var/lib/mysql/。
- 将之前从服务器A传过来的备份文件复制到B的数据目录中对应的 app1 文件夹下。
- # 在服务器B的shell中执行
- cp /data/restore/app1/*.ibd /var/lib/mysql/app1/
- cp /data/restore/app1/*.cfg /var/lib/mysql/app1/
复制代码
- 修正文件权限。
这是非常容易被忽略但至关重要的一步。新复制的文件属主必须是 mysql 用户。- chown -R mysql:mysql /var/lib/mysql/app1/
复制代码 - 导入表空间(Import Tablespace)。
现在,将这些新的数据文件关联到表结构上。
- 登录服务器B的MySQL,并对每一张表执行:
- ALTER TABLE app1.your_table_name IMPORT TABLESPACE;
复制代码 - 同样,你可以用SQL批量生成所有命令:
- SELECT CONCAT('ALTER TABLE ', table_schema, '.', table_name, ' IMPORT TABLESPACE;')
- FROM information_schema.tables
- WHERE table_schema = 'app1';
复制代码
- 检查和授权。
- 检查数据是否恢复成功。
- USE app1;
- SHOW TABLES;
- SELECT COUNT(*) FROM your_table_name;
复制代码 - 数据本身已经恢复,但服务器B上的用户可能还没有访问 app1 数据库的权限。根据需要为相关用户授权。
- GRANT ALL PRIVILEGES ON app1.* TO 'some_user'@'localhost';
- FLUSH PRIVILEGES;
复制代码
总结
通过以上步骤,已经成功地将服务器A的 app1 数据库,在不影响服务器B任何现有数据的情况下,完整地迁移了过去。整个过程的核心是利用了 Percona XtraBackup 的 --databases 部分备份功能和 --export 传输表空间功能。
如果需要对单表进行备份和恢复 可以采用如下命令,恢复过程大同小异- xtrabackup --backup --datadir=/var/lib/mysql --target-dir=/data/backups/ \
- --tables="^test[.].*"
复制代码 来源:豆瓜网用户自行投稿发布,如果侵权,请联系站长删除 |