1、 mysqldump 方法
使用 mysqldump 方法会生成一个 .sql 文件,使用命令执行文件即可复制表成功。
mysqldump -h$host -P$port -u$user --add-locks [--no-create-info] --single-transaction --set-gtid-purged=OFF db1 t --where="a>900" --result-file=/client_tmp/t.sql
参数详解:
--single-transaction
:创建一致性快照而非加表锁,适合 InnoDB 表的在线备份,不阻塞读写操作,而是使用 START TRANSACTION WITH CONSISTENT SNAPSHOT 的方法;--add-locks=0
:不在输出文件中添加LOCK TABLES t WRITE;
语句,避免导入时锁定目标表--no-create-info
:仅导出数据,不包含表结构定义(需确保目标表已存在且结构一致)--set-gtid-purged=OFF
:不输出 GTID 相关信息,避免复制到不同 GTID 环境时的冲突--where
:指定数据过滤条件,实现部分数据复制--result-file
:指定输出文件路径,文件生成在客户端机器而非服务器
使用场景:
- 需要复制部分数据(通过 WHERE 条件筛选)
- 跨不同 MySQL 版本或存储引擎迁移数据
- 不具备服务器文件系统访问权限时
- 需要对导出数据进行编辑后再导入的场景
注意事项:
- 对于大表,导出和导入速度较慢,会生成大量 INSERT 语句
- WHERE 条件不能使用 JOIN 等复杂查询
- 导出过程中会扫描全表,可能影响源库性能
- 导入时会执行大量 INSERT,可能导致目标库 IO 压力增大
导入方法:
mysql -h$host -P$port -u$user -p db2 < /client_tmp/t.sql
2、物理拷贝方法
在 MySQL 5.6 版本引入了可传输表空间(transportable tablespace)的方法,可以通过导出 + 导入表空间的方式,实现物理拷贝表的功能。
假设我们现在的目标是在 db1 库下,复制一个跟表 t 相同的表 r,具体的执行步骤如下:
执行 create table r like t ,创建一个相同表结构的空表;
执行 alter table r discard tablespace,这时候 r.ibd 文件会被删除;
执行 flush table t for export,这时候 db1 目录下会生成一个 t.cfg 文件;
在 db1目录下执行 cp t.cfg r.cfg; cp t.ibd r.ibd;这两个命令;
例如:
cp /path/to/mysql/data/db1/t.cfg /path/to/mysql/data/db1/r.cfg
cp /path/to/mysql/data/db1/t.ibd /path/to/mysql/data/db1/r.ibd
# 确保文件权限正确
chown mysql:mysql /path/to/mysql/data/db1/r.*
执行 unlock tables,这时候t.cfg文件会被删除;
执行 alter table r import tablespace,将这个 r.ibd 文件作为表 r 的新的表空间,由于这个文件的数据内容和 t.ibd 是相同的,所以表 r 中就有了和表 t 相同的数据。
注意事项:
- 执行
FLUSH TABLE ... FOR EXPORT
后,源表将处于只读状态,直至执行UNLOCK TABLES
,需控制此阶段时长 IMPORT TABLESPACE
操作会修改每个数据页的表空间 ID,大表(TB 级)可能需要一定时间,但仍远快于逻辑导入- 必须确保源表和目标表的表结构完全一致,否则导入会失败
- 操作过程需要服务器文件系统的访问权限
- 仅适用于 InnoDB 存储引擎的表
- 拷贝的是完整表数据,无法进行部分数据筛选
- 建议在低峰期执行,避免影响线上业务
优势:
- 速度极快,尤其适合大型表(GB/TB 级)
- 几乎不产生额外的 IO 负载(除了文件拷贝)
- 是误删表后快速恢复数据的首选方法
3. 两种方法的对比与选择建议
特性 | mysqldump 方法 | 物理拷贝方法 |
---|---|---|
速度 | 慢(尤其大表) | 极快 |
灵活性 | 可筛选部分数据 | 只能全表拷贝 |
权限要求 | 仅需数据库访问权限 | 需要服务器文件系统访问权限 |
存储引擎支持 | 支持所有引擎 | 仅支持 InnoDB |
在线操作 | 不阻塞读写 | 源表在部分阶段只读 |
跨版本支持 | 好 | 有限制(需兼容表空间格式) |
适用场景 | 小表、部分数据复制、跨环境迁移 | 大表全量复制、快速恢复 |
3、小结
- 物理拷贝的方式速度最快,尤其对于大表拷贝来说是最快的方法。如果出现误删表的情况,用备份恢复出误删之前的临时库,然后再把临时库中的表拷贝到生产库上,是恢复数据最快的方法。但是,这种方法的使用也有一定的局限性:
- 必须是全表拷贝,不能只拷贝部分数据;
- 需要到服务器上拷贝数据,在用户无法登录数据库主机的场景下无法使用;
- 由于是通过拷贝物理文件实现的,源表和目标表都是使用 InnoDB 引擎时才能使用。
- 用 mysqldump 生成包含 INSERT 语句文件的方法,可以在 where 参数增加过滤条件,来实现只导出部分数据。这个方式的不足之一是,不能使用 join 这种比较复杂的 where 条件写法。