Mysql-如何快速地复制一张表

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、小结

  1. 物理拷贝的方式速度最快,尤其对于大表拷贝来说是最快的方法。如果出现误删表的情况,用备份恢复出误删之前的临时库,然后再把临时库中的表拷贝到生产库上,是恢复数据最快的方法。但是,这种方法的使用也有一定的局限性:
    • 必须是全表拷贝,不能只拷贝部分数据;
    • 需要到服务器上拷贝数据,在用户无法登录数据库主机的场景下无法使用;
    • 由于是通过拷贝物理文件实现的,源表和目标表都是使用 InnoDB 引擎时才能使用。
  2. 用 mysqldump 生成包含 INSERT 语句文件的方法,可以在 where 参数增加过滤条件,来实现只导出部分数据。这个方式的不足之一是,不能使用 join 这种比较复杂的 where 条件写法。
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇