MySQL进行数据离线迁移的实现方案

 更新时间:2026年02月26日 08:47:27   作者:西门吹雪分身  
在实际的业务需求中,mysql数据库往往需要从一个服务器迁移或者导出到另外一台服务器,这个数据导入导出的工作,是不可避免的,所以本文介绍了MySQL数据迁移的物理操作方式,需要的朋友可以参考下

在实际的业务需求中,mysql数据库往往需要从一个服务器迁移或者导出到另外一台服务器。这个数据导入导出的工作,是不可避免的。

mysql对于数据的导入导出提供了逻辑操作与物理操作两种方式,其中mysqdump的逻辑操作往往需要生成SQL文件,如果数据量比较大,可能执行的效果比较差,耗时比较长。本文主要介绍一下基于mysql文件层面的物理操作,也可以叫做冷备份。

mysql的相关官网说明

mysql官网

Transportable Tablespace(可传输表空间) 是 MySQL InnoDB 存储引擎提供的一种机制,允许用户将某个表的表空间文件(.ibd)及其元数据校验文件(.cfg)从一台服务器“运输”到另一台服务器,并直接挂载到目标数据库的表结构上。

核心原理
InnoDB 表空间文件内部包含了一个唯一的 Tablespace ID 和 Schema 指纹。直接拷贝 .ibd 文件时,目标库的元数据(Data Dictionary)中记录的 ID 与文件内部的 ID 不一致,导致无法识别。

  • .ibd实际的数据文件
  • .cfg:由 FLUSH TABLES … FOR EXPORT 命令生成。它包含了表空间的元数据副本(包括 Tablespace ID、Schema 校验和、页大小等)。
  • 流程本质:
    1. 目标库先创建一个空表,生成一个新的空的 .ibd。
    2. 执行 DISCARD TABLESPACE:目标库删除这个空的 .ibd,并进入“等待导入”状态。
    3. 放入源库的 .ibd 和 .cfg。
    4. 执行 IMPORT TABLESPACE:目标库读取 .cfg,验证 .ibd 的完整性和一致性。如果通过,它将更新内部数据字典,将现有的 .ibd 文件“认领”为该表的数据文件。

详细的操作流程

假设我们要迁移表 users,数据库为 test_db。

前提条件:

  • 源库和目标库 MySQL 大版本一致(如都是 5.7 或 8.0)。
  • 源库和目标库的 innodb_file_per_table 均为 ON。
  • 目标库已创建好结构完全一致的表。

第一阶段:在源库(Source)生成文件

这一步的目的是获取一份一致性快照数据文件配套的校验文件

  1. 确保表是可传输的(通常默认就是,但显式执行一次更稳妥):
USE test_db;
-- 这一步会刷新脏页到磁盘,并锁定表进行元数据冻结
FLUSH TABLES users FOR EXPORT;

注意:执行此命令后,表 users 会被锁定为只读(Read Only),直到你解锁或复制完文件。其他会话对该表的写操作会被阻塞。

  1. 复制文件
    保持终端窗口不关闭(保持锁状态),打开另一个终端或通过脚本复制文件。
    找到数据目录(通常是 /var/lib/mysql/test_db/):
    • users.ibd:数据文件。
    • users.cfg:关键文件,包含元数据校验信息。
# 在另一个终端执行
cp /var/lib/mysql/test_db/users.{ibd,cfg} /tmp/backup_for_migration/

# 确认文件已复制完成
ls -lh /tmp/backup_for_migration/
  1. 解锁源库
    文件复制完成后,必须立即解锁,恢复业务写入。
    回到第一个执行 SQL 的终端:
UNLOCK TABLES;

此时源库业务恢复正常。

第二阶段:在目标库(Target)准备环境

  1. 创建结构一致的表
    在目标库执行与源库完全相同的 CREATE TABLE 语句。
CREATE DATABASE IF NOT EXISTS test_db;
USE test_db;

CREATE TABLE users (
    id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    username VARCHAR(50) NOT NULL,
    email VARCHAR(100),
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
    -- 必须与源库完全一致,包括字符集、排序规则、索引
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

提示:可以用 SHOW CREATE TABLE users\G 在源库查看精确语句。

  1. 丢弃自动生成的表空间:

刚才建表时,InnoDB 已经生成了一个空的 users.ibd。需要删掉它,以便导入旧的。

ALTER TABLE users DISCARD TABLESPACE;

执行后,去操作系统查看 /var/lib/mysql/test_db/users.ibd,它应该已经消失了。此时表存在,但无法读写数据。

第三阶段:导入文件到目标库

  1. 拷贝文件到目标数据目录:
    将第一阶段生成的 users.ibd 和 users.cfg 上传到目标库对应的数据目录。
# 假设文件在 /tmp/backup_for_migration/
cp /tmp/backup_for_migration/users.{ibd,cfg} /var/lib/mysql/test_db/
  1. 修正文件权限(至关重要):
    MySQL 进程通常以 mysql 用户运行。如果文件归属是 root,导入会失败。
chown mysql:mysql /var/lib/mysql/test_db/users.{ibd,cfg}
chmod 660 /var/lib/mysql/test_db/users.{ibd,cfg}
  1. 执行导入命令
    登录目标库 MySQL:
USE test_db;
ALTER TABLE users IMPORT TABLESPACE;

  • 如果成功:无任何输出,表立即变为可用状态。
  • 如果失败:会报错。常见原因包括:
    • Schema mismatch:建表语句不一致(字段类型、顺序、字符集等)。
    • Tablespace ID mismatch:通常是因为没执行 DISCARD TABLESPACE 或者 .cfg 文件不匹配。
  1. 验证数据:
SELECT COUNT(*) FROM users;
SELECT * FROM users LIMIT 5;

特点与限制

优点

  1. 速度极快:不涉及逻辑导出(SQL 生成)和导入(SQL 解析执行),本质是文件拷贝,适合 TB 级大表迁移。
  2. 节省 IO:不会像 mysqldump 那样产生巨大的重做日志(Redo Log)和二进制日志(Binlog)压力(导入时可以暂时关闭 Binlog)。
  3. 支持分区表:可以单独导入某个分区,也可以导入整个分区表。

限制与注意事项

4. 版本严格限制:

  • 源和目标必须是相同的大版本(如 5.7 -> 5.7, 8.0 -> 8.0)。
  • 跨大版本(如 5.6 -> 8.0)通常不支持,因为 .ibd 内部格式可能发生变化。
  1. 架构一致:
  • 表结构(DDL)必须比特级一致。哪怕是字符集 utf8 和 utf8mb4 的区别,或者自增列初始值不同,都可能导致 Schema mismatch 错误。
  1. 只针对 InnoDB:MyISAM 或其他引擎不适用。
  2. 外键约束:如果表之间有外键约束,导入过程可能会比较复杂,建议先禁用外键检查 (SET FOREIGN_KEY_CHECKS=0),导入后再开启。
  3. 只读窗口:在源库执行 FLUSH TABLES … FOR EXPORT 期间,该表是只读的。虽然时间很短(仅拷贝文件的时间),但在高并发场景下仍需注意。

总结

Transportable Tablespace 是 MySQL 官方提供的“物理备份/迁移”方案。

  • 核心命令组合:FLUSH TABLES … FOR EXPORT (源) + DISCARD TABLESPACE (目标) + IMPORT TABLESPACE (目标)
  • 关键文件:.ibd (数据) + .cfg (元数据校验)
  • 适用场景:海量数据快速迁移、表空间损坏后的单表恢复、跨实例克隆大表

以上就是MySQL进行数据离线迁移的实现方案的详细内容,更多关于MySQL数据离线迁移的资料请关注脚本之家其它相关文章!

相关文章

  • 如何优化sql中的orderBy语句

    如何优化sql中的orderBy语句

    这篇文章主要介绍了如何优化sql中的orderBy语句,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-09-09
  • 关于MySQL innodb_autoinc_lock_mode介绍

    关于MySQL innodb_autoinc_lock_mode介绍

    下面小编就为大家带来一篇关于MySQL innodb_autoinc_lock_mode介绍。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-03-03
  • mysql数据库入门第一步之创建表

    mysql数据库入门第一步之创建表

    关于mysql介绍网上一搜一大堆,这里就不再介绍了,我之后的mysql文章只讲最简单基础的用法,主要是为java程序服务的.文中有非常详细的图文示例,需要的朋友可以参考下
    2021-05-05
  • MySQL的重装问题解决方法

    MySQL的重装问题解决方法

    最近在工作上遇到了MySQL重装的问题,今天记录一下我的解决过程。不论我用控制面板的卸载删除程序方式还是安全卫士的卸载,都会遇到一个问题,就是安装到如下图位置,server start时就程序无响应了,一直死在那里
    2013-04-04
  • MySQL事务的SavePoint简介及操作

    MySQL事务的SavePoint简介及操作

    SavePoint是数据库事务中的一个概念, 可以将整个事务切割为不同的小事务, 可以选择将状态回滚到某个小事务发生时的样子,本文给大家分享MySQL事务的SavePoint重要操作,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2023-01-01
  • mysql如何比对两个数据库表结构的方法

    mysql如何比对两个数据库表结构的方法

    这篇文章主要介绍了mysql如何比对两个数据库表结构的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-09-09
  • Mysql使用聚合函数时需要注意事项

    Mysql使用聚合函数时需要注意事项

    聚合函数作用于一组数据,并对一组数据返回一个值,常见的聚合函数:SUM()、MAX()、MIN()、AVG()、COUNT(),这篇文章主要介绍了Mysql使用聚合函数时需要注意事项,需要的朋友可以参考下
    2024-08-08
  • mysql查询本周内每天统计量按天展示的示例代码

    mysql查询本周内每天统计量按天展示的示例代码

    本文主要介绍了mysql查询本周内每天统计量按天展示的示例代码,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-05-05
  • mysql8.0.25升级到mysql8.0.30全过程

    mysql8.0.25升级到mysql8.0.30全过程

    本文介绍了MySQL版本升级的主要步骤,包括查看需升级版本、停止服务、下载8.0.30新版、解压安装包及备份旧文件,总结为个人经验分享,供读者参考
    2025-10-10
  • Mysql的timeout以及python重连方式

    Mysql的timeout以及python重连方式

    这篇文章主要介绍了Mysql的timeout以及python重连方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-07-07

最新评论