MariaDB/MySQL備份和恢復(二):數據導入、導出


MariaDB/MySQL備份恢復系列:
備份和恢復(一):mysqldump工具用法詳述
備份和恢復(二):導入、導出表數據
備份和恢復(三):xtrabackup用法和原理詳述


1.導出、導入數據

load data infileselect into outfile語句是配套的。select into outfile語句是將檢索出來的數據按格式導出到文件中,數據遷移跨數據庫系統時,該選項很有用,因為它可以指定分隔符。load data infile是將帶有格式的數據文件導入到表中。

導出、導入數據時需要指定格式(如不指定,則使用默認)。格式涉及幾個方面:字段分隔符、行分隔符、引用符號、轉義符號。

還需注意一點,默認情況下(MySQL 5.6.34之后)這兩個語句無法執行成功,因為全局變量secure_file_priv的默認值為null,它表示禁用這兩種語句的導入導出。

所以應該將其設置為空(不指定任何值)或者指定一個目錄,將來該目錄中的所有文件都可以進行mysql file類的交互。當然,變量指定的目錄必須已經存在,且mysql系統用戶和組必須對該目錄有讀寫權限。

mkdir /data
chown -R mysql.mysql /data

這個變量是全局靜態變量,只能在mysqld實例未啟動的時候才能修改。所以將其寫入配置文件。

[mysqld]
secure-file-priv=/data
# 或者
# secure-file-priv=

查看變量。

select @@global.secure_file_priv;
+---------------------------+
| @@global.secure_file_priv |
+---------------------------+
| /data/                    |
+---------------------------+

再看這兩個語句的語法:

SELECT ... INTO OUTFILE 'file_name'
        [CHARACTER SET charset_name]
        [export_options]
 
LOAD DATA [LOW_PRIORITY | CONCURRENT] [LOCAL] INFILE 'file_name'
    [REPLACE | IGNORE]
    INTO TABLE tbl_name
    [CHARACTER SET charset_name]
        [export_options]
    [IGNORE number {LINES|ROWS}]
    [(col_name_or_user_var,...)]
    [SET col_name = expr,...]
 
 
export_options:
    [{FIELDS | COLUMNS}
        [TERMINATED BY 'string']
        [[OPTIONALLY] ENCLOSED BY 'char']
        [ESCAPED BY 'char']
    ]
    [LINES
        [STARTING BY 'string']
        [TERMINATED BY 'string']
    ]

其中'char'表示只能使用一個字符,'string'表示可以指定多個字符。

fields terminated by 'string'指定字段分隔符;enclosed by 'char'指定所有字段都使用char符號包圍,如果指定了optionally則只用在字符串和日期數據類型等字段上,默認未指定;escaped by 'char'指定轉義符。

lines starting by 'string'指定行開始符,如每行開始記錄前空一個制表符;lines terminated by 'string'為行分隔符。

要注意,在幾種情況下需要使用轉義符:數據中含有轉義符本身或者字段分隔符。當指定了字段引用符enclosed by時,如果數據中含有字段引用符,則也需要轉義,若未指定enclosed by,則默認不使用字段引用符,所以無需轉義。

以下為它們的默認值:

fileds terminated by '\t' enclosed by '' escaped by '\\'
lines terminated by '\n' starting by ''

看上去語法還挺復雜的,使用示例來說明就很清晰易懂了。

給定如下表結構和數據。

create or replace table t(id int primary key,sex char(3),name char(20),ins_day date);

insert into t values(1,'nan','longshuai1','2010-04-19'),
                    (2,'nan','longshuai2','2011-04-19'),
                    (3,'nv','xiaofang1','2012-04-19'),
                    (4,'nv','xiaofang2','2013-04-19'),
                    (5,'nv','xiaofang3','2014-04-19'),
                    (6,'nv','xiaofang4','2015-04-19'),
                    (7,'nv','tun\'er','2016-04-19'),
                    (8,'nan','longshuai3','2017-04-19');

1.1 select into outfile導出數據

使用默認設置:

select * from t into outfile '/data/t_data.sql';

\! cat /data/t_data.sql
1       nan     longshuai1      2010-04-19
2       nan     longshuai2      2011-04-19
3       nv      xiaofang1       2012-04-19
4       nv      xiaofang2       2013-04-19
5       nv      xiaofang3       2014-04-19
6       nv      xiaofang4       2015-04-19
7       nv      tun'er  2016-04-19
8       nan     longshuai3      2017-04-19

指定字段分隔符",",使用單引號包圍各字段,每行前加上制表符。

select * from t into outfile '/data/t_data1.sql' fields terminated by ',' enclosed by '\'' lines starting by '\t' terminated by '\n';

\! cat /data/t_data1.sql
        '1','nan','longshuai1','2010-04-19'
        '2','nan','longshuai2','2011-04-19'
        '3','nv','xiaofang1','2012-04-19'
        '4','nv','xiaofang2','2013-04-19'
        '5','nv','xiaofang3','2014-04-19'
        '6','nv','xiaofang4','2015-04-19'
        '7','nv','tun\'er','2016-04-19'
        '8','nan','longshuai3','2017-04-19'

1.2 load data infile導入數據

要導入格式化后的純數據,可以使用load data infile,加載純數據的插入方式比直接執行insert插入至少快20多倍。但在內部,它們其實是等價行為,load data infile也會觸發insert相關觸發器。

其中可以使用local關鍵字表示從客戶端主機讀取文件,如果沒有指定local則表示從服務端主機讀取文件。

fields和lines的相關選項和select ... into outfile是一樣的,只不過load data infile多了幾個選項。其中ignore N lines|rows表示忽略前N行數據不導入,col_name_or_user_var表示按此處給定的字段和順序來導入數據,set col_name=expr表示對列進行一些表達式運算,如給某數值字段加5,給某字符串列尾部加上@qq.com字符等。

例如要加載如下文件到test.t表中。

cat /data/t_data.txt
1       nan     longshuai1      2010-04-19
2       nan     longshuai2      2011-04-19
3       nv      xiaofang1       2012-04-19
4       nv      xiaofang2       2013-04-19
5       nv      xiaofang3       2014-04-19
6       nv      xiaofang4       2015-04-19
7       nv      tun'er  2016-04-19
8       nan     longshuai3      2017-04-19

首先刪除表中數據,再導入。

truncate test. t;
load data infile '/data/t_data.sql' into table test.t fields terminated by '\t';

將如下包含字段分隔符",",字段引用符"'",轉義符"\",行前綴"\t"的文件加載到test.t表中。

[root@xuexi ~]# cat /data/t_data1.sql
        '1','nan','longshuai1','2010-04-19'
        '2','nan','longshuai2','2011-04-19'
        '3','nv','xiaofang1','2012-04-19'
        '4','nv','xiaofang2','2013-04-19'
        '5','nv','xiaofang3','2014-04-19'
        '6','nv','xiaofang4','2015-04-19'
        '7','nv','tun\'er','2016-04-19'
        '8','nan','longshuai3','2017-04-19'

首先刪除表中數據,然后加載。

truncate test.t;
load data infile '/data/t_data1.sql' into table test.t fields terminated by ',' enclosed by '\'' escaped by '\\' lines starting by '\t' terminated by '\n';

若要忽略前兩行,則:

truncate test.t;
load data infile '/data/t_data1.sql' into table test.t fields terminated by ',' enclosed by '\'' escaped by '\\' lines starting by '\t' terminated by '\n' ignore 2 rows;

如果想在id列值加上5,則:

truncate test.t;
load data infile '/data/t_data1.sql' into table test.t fields terminated by ',' enclosed by '\'' escaped by '\\' lines starting by '\t' terminated by '\n' set id=id+5;

如果想name列后加上"@qq.com"字符串,則:

truncate test.t;
load data infile '/data/t_data1.sql' into table test.t fields terminated by ',' enclosed by '\'' escaped by '\\' lines starting by '\t' terminated by '\n' set name=concat(name,'@qq.com');

如果想同時執行上面兩個set,則:

truncate test.t;
load data infile '/data/t_data1.sql' into table test.t fields terminated by ',' enclosed by '\'' escaped by '\\' lines starting by '\t' terminated by '\n' set name=concat(name,'@qq.com'), id=id+5;

1.3 mysqldump導出數據

select into outfile功能類似的語句還有:此方法導出的數據中還包含了列名。

mysql -uroot -p123456 -e "select * from test.t">/tmp/t_data2.sql

cat /tmp/t_data2.sql
id      sex     name    ins_day
1       nan     longshuai1      2010-04-19
2       nan     longshuai2      2011-04-19
3       nv      xiaofang1       2012-04-19
4       nv      xiaofang2       2013-04-19
5       nv      xiaofang3       2014-04-19
6       nv      xiaofang4       2015-04-19
7       nv      tun'er  2016-04-19
8       nan     longshuai3      2017-04-19

雖說select ... into outfile導出數據后可修改性和加載性非常強,但是畢竟沒有導出結構。要導出結構,可以使用mysqldump的"--tab"選項,它既會導出表的結構定義語句到同表名的.sql文件中,還會導出數據到同表名的.txt文件中。

mysqldump -uroot -p123456 --tab /data test t;

ls -l /data/t.*
-rw-r--r-- 1 root  root  1408 Apr 19 14:46 /data/t.sql   # test.t表定義語句
-rw-rw-rw- 1 mysql mysql  211 Apr 19 14:46 /data/t.txt   # test.t表內數據

mysqldump的"--tab"選項同樣可以指定各種分隔符。如"--fields-terminated-by=...,--fields-enclosed-by=...,--fields-optionally-enclosed-by=...,--fields-escaped-by=..."。以下是指定字段分隔符為","。

mysqldump -uroot -p123456 --tab /data --fields-terminated-by=',' test t;

cat /data/t.txt
1,nan,longshuai1,2010-04-19
2,nan,longshuai2,2011-04-19
3,nv,xiaofang1,2012-04-19
4,nv,xiaofang2,2013-04-19
5,nv,xiaofang3,2014-04-19
6,nv,xiaofang4,2015-04-19
7,nv,tun'er,2016-04-19
8,nan,longshuai3,2017-04-19

1.4 mysqlimport導入數據

mysqlimport和load data infile的本質是一樣的。mysqlimport在執行時會像服務端發送load data infile來加載數據,並且mysqlimport支持多進程並行導入多張表的數據。

mysqlimport的語法和load data infile基本一致。不同的是它在MySQL/MariaDB的外部執行,且可以一次性並行多線程導入多張表(並非並行導入一張表),所以能更快地導入所有數據。

mysqlimport [OPTIONS] database textfile...

注意:mysqlimport只能指定數據庫名來導入,所以導入的文件名必須和數據庫中的表名相對應(文件名后綴無所謂)。例如文件名為stu2.sql,而表名為student則無法導入,它會找stu2這個表。

例如,將以下格式的文件t.txt使用mysqlimport導入到test.t表中:

[root@xuexi ~]# cat /data/t.txt
1,nan,longshuai1,2010-04-19
2,nan,longshuai2,2011-04-19
3,nv,xiaofang1,2012-04-19
4,nv,xiaofang2,2013-04-19
5,nv,xiaofang3,2014-04-19
6,nv,xiaofang4,2015-04-19
7,nv,tun'er,2016-04-19
8,nan,longshuai3,2017-04-19

[root@xuexi ~]# mysqlimport -uroot -p123456 --fields-terminated-by=',' test '/data/t.txt'

使用"--use-threads"選項可以指定導入線程數。

例如,下面指定兩個線程,導入兩張表到數據庫test庫中的t1和t2表中。

mysqlimport -uroot -p123456 --use-threads=2 --fields-terminated-by=',' test '/data/t1.txt' '/data/t2.txt'


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM