mysql独立表空间迁移
在MySQL中,使用独立表空间(innodb_file_per_table=ON
)时,每个表对应独立的 .ibd
文件(存储数据和索引)和 .frm
文件(存储表结构,MySQL 8.0 后合并到 .ibd
中)。迁移独立表空间的表可以通过以下两种方法实现,适用于同版本/跨版本迁移或跨服务器迁移:
方法一:直接复制 .ibd
文件(适用于同版本迁移)
此方法适用于 相同MySQL版本 之间的迁移(版本差异可能导致文件格式不兼容),步骤如下:
1. 准备源表
在源数据库中,确保表使用独立表空间,并刷新表以确保数据写入磁盘:
-- 确认表使用独立表空间(输出为 ON)
SHOW VARIABLES LIKE 'innodb_file_per_table';-- 锁定表并刷新到磁盘(避免文件读写冲突)
FLUSH TABLES `表名` FOR EXPORT;
2. 复制表文件
在源服务器的数据库目录(可通过 SHOW VARIABLES LIKE 'datadir';
查看)中,复制以下文件到目标服务器:
- 表结构文件:
表名.frm
(MySQL 5.7及之前) - 表空间文件:
表名.ibd
示例(假设数据库名为 testdb
,表名为 user
):
# 源服务器复制文件(需root权限)
cp /var/lib/mysql/testdb/user.frm /tmp/
cp /var/lib/mysql/testdb/user.ibd /tmp/
3. 在源库解锁表
完成文件复制后,在源数据库中解锁表:
UNLOCK TABLES;
4. 在目标库准备表结构
在目标数据库中,先创建相同结构的表(必须保证表结构完全一致,包括字段、类型、索引等):
-- 在目标库创建同名数据库(若不存在)
CREATE DATABASE IF NOT EXISTS testdb;
USE testdb;-- 创建与源表完全一致的表结构(可从源库导出CREATE语句)
CREATE TABLE `user` (`id` int(11) NOT NULL AUTO_INCREMENT,`name` varchar(50) NOT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
5. 替换目标库的 .ibd
文件
- 先删除目标库中新建表的
.ibd
文件(保留表结构):ALTER TABLE `user` DISCARD TABLESPACE;
- 将复制的
user.frm
(若有)和user.ibd
文件复制到目标库的数据库目录:# 目标服务器操作(需修改文件权限为mysql用户) cp /tmp/user.frm /var/lib/mysql/testdb/ cp /tmp/user.ibd /var/lib/mysql/testdb/ chown mysql:mysql /var/lib/mysql/testdb/user.*
- 导入表空间文件:
ALTER TABLE `user` IMPORT TABLESPACE;
6. 验证迁移结果
在目标库中查询表数据,确认迁移成功:
SELECT * FROM `user` LIMIT 10;
方法二:使用 mysqldump
迁移(适用于跨版本/跨服务器)
若版本不同或需更安全的迁移方式,推荐使用 mysqldump
导出表结构和数据,步骤如下:
1. 导出源表
在源服务器执行以下命令,导出表结构和数据(--single-transaction
确保InnoDB一致性):
mysqldump -u 用户名 -p --databases testdb --tables user --single-transaction > user.sql
2. 传输备份文件到目标服务器
scp user.sql 目标服务器IP:/tmp/
3. 在目标库导入
在目标服务器执行以下命令,导入表结构和数据:
mysql -u 用户名 -p testdb < /tmp/user.sql
4. 验证数据
登录目标库查询数据,确认迁移正确。
方法三:使用 xtrabackup
迁移(适用于大表高效迁移)
Percona XtraBackup 是一款开源工具,可热备份InnoDB表,适合GB级以上大表迁移,步骤如下:
1. 安装 xtrabackup
在源服务器和目标服务器安装:
# CentOS 7 示例
yum install -y https://repo.percona.com/yum/percona-release-latest.noarch.rpm
percona-release enable-only tools release
yum install -y percona-xtrabackup-80 # 对应MySQL 8.0,其他版本需匹配
2. 源库备份表
xtrabackup --user=用户名 --password=密码 --databases=testdb.user --backup --target-dir=/tmp/backup/
3. 准备备份(使数据处于一致性状态)
xtrabackup --prepare --target-dir=/tmp/backup/
4. 复制备份到目标服务器
scp -r /tmp/backup/ 目标服务器IP:/tmp/
5. 目标库恢复
先停止目标库MySQL服务,清空数据目录,再恢复:
# 目标服务器操作
systemctl stop mysqld
rm -rf /var/lib/mysql/* # 确保数据目录为空
xtrabackup --copy-back --target-dir=/tmp/backup/
chown -R mysql:mysql /var/lib/mysql
systemctl start mysqld
注意事项
- 版本兼容性:方法一(直接复制
.ibd
)仅适用于 相同MySQL版本(尤其是InnoDB版本一致),否则可能因文件格式差异导致失败。 - 表结构一致性:迁移前必须确保目标表结构与源表完全一致(字段、类型、索引、字符集等)。
- 权限问题:复制文件后需将所有者改为
mysql:mysql
,否则MySQL无法读取。 - 事务与锁:迁移过程中避免对源表进行写入操作,或使用
FLUSH TABLES ... FOR EXPORT
锁定表确保一致性。 - MySQL 8.0 差异:MySQL 8.0 取消了
.frm
文件,表结构存储在.ibd
中,迁移时只需处理.ibd
文件。
根据场景选择合适的方法:小表推荐 mysqldump
,同版本大表推荐直接复制 .ibd
,超大型表推荐 xtrabackup
。