Ⅰ、傳統姿勢
這種方法需要提前設置一個參數
- secure_file_priv
value | meaning |
---|---|
NULL | 不允許導入導出 |
'' | 可以導入到任何地址 |
'/tmp' | 導入到具體地址 |
這個參數是只讀參數,只能修改my.cnf后重啟
做這種操作需要file權限
1.1 導出
select * into outfile 'xxx.data' from xxx #sql語句隨便寫
fields terminated by 'string' 指定分隔符,默認tab
lines terminated by 'string' 指定結束符,默認換行
測試一把
(root@localhost) [test]> select * from data_load;
+------+------+
| a | b |
+------+------+
| 1 | 2 |
| 2 | 3 |
| 3 | 4 |
+------+------+
3 rows in set (0.00 sec)
(root@localhost) [test]> select * into outfile '/tmp/data_load.data' from data_load;
Query OK, 3 rows affected (0.01 sec)
[root@VM_0_5_centos tmp]# cat data_load.data
1 2
2 3
3 4
導出的數據和mysqldump不太一樣,打開來看會發現里面是每個列的數據,tab來分割
1.2 導入
create table xxx like xxx;
數據文件里不是sql語句,用loaddata導入,不用額外解析insert,比較快
load data infile 'xxx' into table xxx
分隔符和結束符不一樣的時候要調整
也測一把
(root@localhost) [test]> create table data_load2 like data_load;
Query OK, 0 rows affected (0.06 sec)
(root@localhost) [test]> load data infile '/tmp/data_load.data' into table data_load2;
Query OK, 3 rows affected (0.01 sec)
Records: 3 Deleted: 0 Skipped: 0 Warnings: 0
(root@localhost) [test]> select * from data_load2;
+------+------+
| a | b |
+------+------+
| 1 | 2 |
| 2 | 3 |
| 3 | 4 |
+------+------+
3 rows in set (0.00 sec)
玩個好玩的
(root@localhost) [test]> create table wanwan(a int, b int, c int);
Query OK, 0 rows affected (0.05 sec)
(root@localhost) [test]> load data infile '/tmp/data_load.data' into table wanwan (a,b) set c=a+b;
Query OK, 3 rows affected, 3 warnings (0.35 sec)
Records: 3 Deleted: 0 Skipped: 0 Warnings: 3
(root@localhost) [test]> select * from wanwan;
+------+------+------+
| a | b | c |
+------+------+------+
| 1 | 2 | 3 |
| 2 | 3 | 5 |
| 3 | 4 | 7 |
+------+------+------+
3 rows in set (0.00 sec)
tips:ignore N lines 可指定不到如前N行
注意:
地理空間的數據類型,列比較特殊,geometry的列,導出的話是一個經度和緯度,導入的時候就要用set a = geometry(a,b);
1.3 load data的缺點
- 針對文本文件,會有限制,比如一篇博客,有很多字符,逗號,tab,等等
其實可以搞成十六進制,再導入進去,但是比較煩
Ⅱ、新式玩法
上面這種常用于異構數據的導入導出,如果一張表非常大,導起來可能會有點慢
myisam表flush一下就可以隨意copy,innodb不行? 那是innodb的信息由數據字典維護,保存在共享表空間中,沒法把它sync到磁盤上
5.6版本開始支持獨立表空間導入與導出(透明表空間傳輸),類似于xtrabackup備份,因為5.6有個新語法flush table ... for export將數據字典sync到disc
要求:兩張表結構一樣,這樣表空間才能互相傳輸
操作步驟:
1、目標服務器:alter table t discard tablespace; 刪除表空間文件
2、源服務器:flush table t for export; 鎖成只讀
show processlist;
waiting for table metadata lock 加了元數據鎖
3、把源實例的表空間和拷貝一份到目標實例
4、源服務器:unlock tables; 釋放鎖
5、調整文件用戶權限
6、目標服務器:alter table t import tablespace; 導入
傻瓜式操作,簡單快捷,不演示了,真的有點累啊!
不希望有warning的話,還有個cfg文件需要處理一下
import并不是秒級別的,和表空間大小有關,需要修改元數據,tablespace里面有space id和page no,兩個ibd文件的space id是完全一樣的,import的時候需要修改一下space id
缺點:
- 可能數據量比較大的話,和xtrabackup一樣會造成一定的io飆升
限制:
- 兩個實例都必須開啟獨立表空間,innodb_file_per_table
- 遷移的兩個實例的innodb_page_size必須一致,并且mysql server版本建議一致
這個特性并沒有得到廣泛應用
Ⅲ、好東西
5.7有個更好的東西,用的比較多(訂單,快遞保留三個月數據)
基于分區表透明表空間傳輸
alter table t1 discard p2,p3 tablespace;
alter table t1 import p2,p3 tablespace;