Sunskey

日拱一卒,不期而至

0%

MySQL 快速复制一张表

MySQL 快速复制一张表

1.使用mysqldump方法,将命令数据导成一组INSERT语句。

mysqldump -h$host -P$port -u$user –add-locks=0 –no-create-info –single-transaction –set-gtid-purged=OFF db1 t –where=”a>900” –result-file=/client_tmp/t.sql

  1. –single-transaction 的作用是,在导出数据的时候不需要对表db1.t加锁,而是使用START TRANSACTION WITH CONSISTENT SNAPSHOT 的方法;
  2. –add-locks 设置为 0,表示在输出的文件结果里,不增加” LOCK TABLES t WRITE;” ;
  3. –no-create-info 的意思是,不需要导出表结构;
  4. –set-gtid-purged=off 表示的是,不输出跟 GTID 相关的信息;
  5. –result-file 指定了输出文件的路径,其中 client 表示生成的文件是在客户端机器上。

之后执行mysql -h127.0.0.1 -P13000 -uroot db2 -e “source /client_tmp/t.sql”

2.导出csv文件

另一种方法是直接将结果导出成.csv文件。

select * from db1.t where a>900 into outfile ‘/server_tmp/t.csv’;

  1. 这条语句会将结果保存在服务端。

  2. into_outfile指定了文件的生成位置(/server_tmp/),这个位置必须受参数secure_file_priv的限制。

  3. 这条命令不会帮助覆盖文件,因此确保文件不存在,存在则会报错。

  4. 这条命令生成的文本文件中,原则上一个数据行对应文本的一行。

得到.csv 导出文件后,你就可以用下面的 load data 命令将数据导入到目标表 db2.t 中.

load data infile ‘/server_tmp/t.csv’ into table db2.t

load data 命令有两种用法

  1. 不加“local”,是读取服务端的文件,这个文件必须自secure_file_priv指定的目录或者子目录下
  2. 加上“local”,读取的是客户端的文件,只要mysql客户端有访问这个文件的权限即可。

select …into outfile 方法不会生成表结构文件,单独导出需要使用如下命令。

mysqldump -h$host -P$port -uuser —single-transaction –set-gtid-purged=OFF db1 t –where=”a>900” –tab=$secure_file_priv

3.物理拷贝方法

MySQL5.6版本引入了可传输表空间的方法,可以通过导出+导入表空间的方式,实现物理拷贝表的功能。

  1. 执行 create table r like t,创建一个相同表结构的空表。

  2. 执行alter table discard table space,这时候r.ibd文件会被删除。

  3. 执行flush table t for export, 这时候db1目录下会生成一个t.cfg文件。

  4. 在db1目录下执行cp t.cfg r.cfg; cp t.ibd r.ibd;这两个命令

  5. 执行unlock tables,这时候t.cfg文件会被删除;

  6. 执行alter table r import table space, 将这个r.ibd文件作为表r的新空间。

注意事项

1.在执行import tablespace的时候,为了让文件里的表空间id和数据字典中的一致,会修改r.ibd的表空间id。

2.flush tables命令之后,db1.t整个表处于只读状态,知道执行unlock tables 命令才释放读锁。