GreenPlum 的数据导入功能作为对数据源的一种扩充,数据导入的方式有:
gpfdist 是 Greenplum 数据库并行文件分发程序。
它可以被外部表和 gpload 用来并行地将外部表文件提供给所有的 Greenplum 数据库 Segment。
它也可以被可写外部表使用,并行接受来自 Greenplum 数据库 Segment 的输出流,并将它们写出到文件中。
总的来说,可以并行读文件数据,通过 segment 将数据读取至 master 中, 可以并行写文件数据,通过 segment 将数据写入文件中。 gpfdist 本身是单进程单线程程序,所以如果需要实现服务端的并行,需要启动多个 gpfdist 服务。
gpfdist [-d ] [-p ] [-l ] [-t ]
[-S] [-w
例如:gpfdist -p 9000
-d 可以指定工作目录,如果没指定,则为当前目录
-l 指定 log 文件,如果没指定,则直接输出到屏幕中
-p 指定服务端口,默认是 8080
-m 指定最大一行数据的大小,单位是 byte,默认是 32768, 即 32K,可配范围是 32K ~ 256M
-S
示例中主要使用的是 gpfdist 协议,使用的文件格式主要是 csv。
只读外部表
CREATE [READABLE] EXTERNAL [TEMPORARY | TEMP] TABLE table_name
( column_name data_type [, ...] | LIKE other_table )
LOCATION ('file://seghost[:port]/path/file' [, ...])
| ('gpfdist://filehost[:port]/file_pattern[#transform=trans_name]'
[, ...]
| ('gpfdists://filehost[:port]/file_pattern[#transform=trans_name]'
[, ...])
| ('pxf://path-to-data?PROFILE=profile_name[&SERVER=server_name][&custom-option=value[...]]'))
| ('s3://S3_endpoint[:port]/bucket_name/[S3_prefix] [region=S3-region] [config=config_file]')
[ON MASTER]
FORMAT 'TEXT'
[( [HEADER]
[DELIMITER [AS] 'delimiter' | 'OFF']
[NULL [AS] 'null string']
[ESCAPE [AS] 'escape' | 'OFF']
[NEWLINE [ AS ] 'LF' | 'CR' | 'CRLF']
[FILL MISSING FIELDS] )]
| 'CSV'
[( [HEADER]
[QUOTE [AS] 'quote']
[DELIMITER [AS] 'delimiter']
[NULL [AS] 'null string']
[FORCE NOT NULL column [, ...]]
[ESCAPE [AS] 'escape']
[NEWLINE [ AS ] 'LF' | 'CR' | 'CRLF']
[FILL MISSING FIELDS] )]
| 'CUSTOM' (Formatter=<formatter_specifications>)
[ ENCODING 'encoding' ]
[ [LOG ERRORS [PERSISTENTLY]] SEGMENT REJECT LIMIT count
[ROWS | PERCENT] ]
只读外部表
指定了csv格式的时候,默认的 分隔符(DELIMITER)为 ‘,’ ,默认的引号值(QUOTE)为 ‘"’,默认的换行符(NEWLINE)为\n。
create external table ext (id int, name char(20))
location ('gpfdist://gp_init:9000/data.csv')
format 'csv';
insert into a select * from ext;
create external table ext2 (id int, name char(20))
location ('gpfdist://gp_init:9000/data.csv',
'gpfdist://gp_init:9000/data2.csv')
format 'csv';
create external table ext6 (id int, name char(20))
location ('gpfdist://gp_init:9000/data*.csv')
format 'csv';
create external table ext7 (id int, name char(20))
location ('gpfdist://gp_init:9000/data.csv',
'gpfdist://gp_init:9001/data2.csv')
format 'csv';
数据文件的内容
[root@gp_init gpfdist]# cat data.csv
0, asdfghjkl;
1, asdfghjkl;
[root@gp_init gpfdist]# cat data2.csv
0, asdfghjkl;
1, asdfghjkl;
postgres=# select * from ext;
id | name
----+----------------------
0 | asdfghjkl;
1 | asdfghjkl;
(2 rows)
postgres=# select * from ext2;
id | name
----+----------------------
0 | asdfghjkl;
1 | asdfghjkl;
0 | asdfghjkl;
1 | asdfghjkl;
(4 rows)
postgres=# select * from ext6;
id | name
----+----------------------
0 | asdfghjkl;
1 | asdfghjkl;
0 | asdfghjkl;
1 | asdfghjkl;
(4 rows)
postgres=# select * from ext7;
id | name
----+----------------------
0 | asdfghjkl;
1 | asdfghjkl;
0 | asdfghjkl;
1 | asdfghjkl;
(4 rows)
只读外部表
gpfdist 支持从管道中读取数据流。
[root@gp_init gpfdist]# mkfifo gpfdist_pipe
cat data.csv > gpfdist_pipe
create external table ext_pipe(id int, name varchar(30))
location ('gpfdist://gp_init:9000/gpfdist_pipe')
format 'csv';
postgres=# select * from ext_pipe ;
id | name
----+-------------
0 | asdfghjkl;
1 | asdfghjkl;
目前可写的外部表只支持 gpfdist 协议。
CREATE WRITABLE EXTERNAL [TEMPORARY | TEMP] TABLE table_name
( column_name data_type [, ...] | LIKE other_table )
LOCATION('gpfdist://outputhost[:port]/filename[#transform=trans_name]'
[, ...])
| ('gpfdists://outputhost[:port]/file_pattern[#transform=trans_name]'
[, ...])
FORMAT 'TEXT'
[( [DELIMITER [AS] 'delimiter']
[NULL [AS] 'null string']
[ESCAPE [AS] 'escape' | 'OFF'] )]
| 'CSV'
[([QUOTE [AS] 'quote']
[DELIMITER [AS] 'delimiter']
[NULL [AS] 'null string']
[FORCE QUOTE column [, ...]] | * ]
[ESCAPE [AS] 'escape'] )]
| 'CUSTOM' (Formatter=<formatter specifications>)
[ ENCODING 'write_encoding' ]
[ DISTRIBUTED BY ({column [opclass]}, [ ... ] ) | DISTRIBUTED RANDOMLY ]
create writable external table extw (id int, name char(20))
location ('gpfdist://gp_init:9000/data.csv')
format 'csv';
create writable external table extw2 (id int, name char(20))
location ('gpfdist://gp_init:9000/data.csv',
'gpfdist://gp_init:9000/data2.csv')
format 'csv';
create writable external table extw3 (id int, name char(20))
location ('gpfdist://gp_init:9000/data.csv',
'gpfdist://gp_init:9001/data2.csv')
format 'csv';
postgres=# create table abc(id int, name char(20));
postgres=# insert INTO abc select * from ext;
postgres=# select count(*) from abc;
count
--------
100000
(1 row)
-- 写入文件
-- 基本上是会把数据平局分给各个文件里。
postgres=# insert INTO extw select * from abc ;
INSERT 0 100000
[root@gp_init gpfdist]# wc -l data.csv
100000 data.csv
postgres=# insert INTO extw2 select * from abc ;
INSERT 0 100000
[root@gp_init gpfdist]# wc -l data.csv data2.csv
50171 data.csv
49829 data2.csv
100000 total
postgres=# insert INTO extw3 select * from abc ;
INSERT 0 100000
[root@gp_init gpfdist]# wc -l data.csv data2.csv
50135 data.csv
49865 data2.csv
100000 total
create writable external table extw4 (id int, name char(20))
location ('gpfdist://gp_init:9000/gpfdist_pipe')
format 'csv';
-- 执行写入操作
postgres=# insert INTO extw4 select * from abc;
[root@gp_init opt]# bash read.sh gpfdist_pipe
100000
1、main
2、gpfdist_init
3、do_read_request
如果是超时事件,则直接发送http_end,后续会关闭连接。
读取socket,如果是返回0,发送 http_end。