SELECT INTO OUTFILE

重要

本文中含有需要您注意的重要提示信息,忽略该信息可能对您的业务造成影响,请务必仔细阅读。

当您需要备份或者迁移云数据库 SelectDB 版中的数据时,可以使用SELECT INTO OUTFILE命令,可以将查询结果导出为文件,并支持通过 S3 或 HDFS 协议将数据导出至远程存储(如 OSS、HDFS 等)。

功能介绍

SELECT INTO OUTFILE可用于备份或者迁移SelectDB中的数据,该命令具有以下特点。

  • 属于同步命令。

    • 该命令执行完毕后,会立即返回一行结果作为导出执行状态。

    • 由于同步机制下任务状态仅在完成后返回,若连接中断,系统无法获取中间状态,因此无法判断导出是否完整完成”。

      为避免任务中断后无法判断导出是否完整,建议您在创建导出任务时,在Properties中配置"success_file_name" = "SUCCESS",任务成功后在输出目录会生成指定标识文件。您可通过验证该文件是否存在,确认导出完整性。

  • 本质是执行了一个SQL查询。

    该命令本质为执行SQL查询,默认采用单线程输出结果。

  • 导出耗时:导出总耗时=查询执行时间+结果集写出耗时

    若处理大规模查询,需通过会话变量query_timeout调大超时阈值。如何设置查询会话变量,请参见查询变量

  • 导出结果为文件。

    该命令用于将查询结果导出为文件。目前支持通过S3HDFS协议导出到远端存储,如OSS、HDFS等。

  • 导出时不检查文件及文件路径是否存在。

    该命令不检查文件及文件路径是否存在,也不会自动创建目录或覆盖现有文件,具体行为完全取决于远端存储系统(如S3/HDFS)的规则。

    SelectDB不会对导出的文件进行任何管理,所有导出文件(包括成功产物及失败残留文件)均需您在远端存储侧自行管理及清理。

使用限制

目前仅支持通过S3HDFS协议导出数据。

注意事项

  • 数据类型不同,支持导出至的文件类型会有所不同。

    • 基本数据类型:支持导出至CSV、PARQUET、CSV_WITH_NAMES、CSV_WITH_NAMES_AND_TYPESORC格式的文件中。

    • 复杂数据类型:

      • 仅支持将复杂数据类型(ARRAY、MAP、STRUCT)导出到CSV、CSV_WITH_NAMES、CSV_WITH_NAMES_AND_TYPESORC格式的文件中。

      • 不支持导出嵌套的复杂数据类型。

  • 结果文件注意事项:

    • 对于结果集为空的查询,依然会产生一个文件。

    • 文件切分会保证一行数据完整的存储在单一文件中,因此文件的大小并不严格等于max_file_size

  • 结果文件内容输出注意事项:

    • 对于部分输出为非可见字符的函数,如BITMAP、HLL类型,输出为\N,即NULL。

    • 目前部分地理位置函数的实际输出值内容为经过编码的二进制字符,请使用ST_AsText进行输出。这类地理位置函数有:

      ST_CIRCLE、ST_POINT、ST_POLYGON、ST_GEOMETRYFROMTEXT、ST_LINEFROMTEXT、ST_GEOMETRYFROMWKB

语法

<query_stmt>
INTO OUTFILE "<file_path>"
[format_as]
[properties]

参数说明

参数名称

是否必填

参数说明

query_stmt

使用SELECT语句,查询需要导出的数据集。

file_path

指向文件存储的路径以及文件前缀。

您也可以省略文件前缀,只指定文件目录,如"hdfs://path/to/"

不指定文件前缀时,最终导出的文件名由实例名称_文件序号以及文件格式后缀组成。

指定文件前缀时,最终导出的文件名由文件前缀、实例名称_文件序号以及文件格式后缀组成。

  • 文件序号由0开始,数量为文件被分割的数量。

    当文件是个单文件时,文件名中没有文件序号。

  • 文件后缀默认为.csv,具体取决于下述format_as指定的导出格式。

例如,file_path

  • "s3://bucket_name/to/my_file_"

  • "hdfs://path/to/my_file_"

其中

  • 文件前缀为my_file_

  • 如果format_as指定为CSV,则文件后缀为csv。

  • 文件是否为单文件。

    • 是单文件,则没有文件序号。最终文件名称则为:my_file_实例名称_0.csv

    • 不是单文件:

      • 文件序号由0开始,依次加1。

      • 数量为文件被分割的数量。

      最终文件名称则为

      my_file_abcdefg_0.csv
      my_file_abcdefg_1.csv
      my_file_abcdegf_2.csv
      ...

format_as

指定导出的格式。

  • 支持CSV、PARQUET、CSV_WITH_NAMES、CSV_WITH_NAMES_AND_TYPESORC。

  • 不设置此参数,默认导出为CSV。

properties

指定导出文件相关属性,以及HDFS、S3的相关属性。详情请参见Properties语法

说明

目前仅支持通过S3HDFS协议进行导出。

Properties语法

Properties的语法如下,支持文件、HDFS、S3相关属性配置。

[PROPERTIES ("key"="value", ...)]
  • 文件相关属性

    参数名称

    是否必填

    参数说明

    column_separator

    列分割符,只用于CSV相关格式。

    line_delimiter

    行分割符,只用于CSV相关格式。

    max_file_size

    单个文件大小限制。如果结果超过这个值,将切割成多个文件。

    • 取值范围:[5 MB, 2 GB]

    • 默认值:1 GB

    当指定导出为ORC文件格式(即format_as参数为ORC)时,实际切分文件的大小是ceil (max_file_size/64) * 64 MB。

    delete_existing_files

    是否删除file_path指定目录下的所有文件。

    • false(默认值):不删除定目录下的所有文件,直接导出文件。

    • true:先删除file_path指定目录下的所有文件,然后导出数据到该目录下。例如:

      • "file_path" = "/user/tmp",则会删除"/user/"下所有文件及目录。

      • "file_path" = "/user/tmp/",则会删除"/user/tmp/"下所有文件及目录。

    警告
    • 指定delete_existing_files = true是一个危险的操作,建议只在测试环境中使用。

    • 若要使用delete_existing_files参数,您可以向阿里云客服提工单,SelectDB技术团队在fe.conf配置文件中添加配置enable_delete_existing_files = true,并重启FE后,delete_existing_files才会生效。

    file_suffix

    指定导出文件的后缀,若不指定该参数,将使用文件格式的默认后缀。

  • HDFS相关属性

    参数名称

    是否必选

    参数说明

    fs.defaultFS

    NameNode地址和端口。

    hadoop.username

    HDFS用户名。

    dfs.nameservices

    Name Service名称,与hdfs-site.xml保持一致。

    dfs.ha.namenodes.[nameservice ID]

    NameNodeID列表,与hdfs-site.xml保持一致。

    dfs.namenode.rpc-address.[nameservice ID].[name node ID]

    NameNodeRPC地址,数量与NameNode数量相同,与hdfs-site.xml保持一致。

    dfs.client.failover.proxy.provider.[nameservice ID]

    HDFS客户端连接活跃NameNodeJava类,通常是org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider

    对于开启Kerberos认证的Hadoop集群,还需要额外设置如下PROPERTIES属性:

    参数名称

    是否必选

    参数说明

    dfs.namenode.kerberos.principal

    HDFS NameNode服务的Principal名称。

    hadoop.security.authentication

    指定认证方式。指定为kerberos以启用Kerberos认证。

    hadoop.kerberos.principal

    指定KerberosPrincipal。

    hadoop.kerberos.keytab

    指定KerberosKeytab文件路径。

  • S3相关属性

    支持S3协议的存储系统,包括但不限于S3,OSS等,都可参考该参数列表进行配置。

    参数名称

    是否必选

    参数说明

    s3.endpoint

    使用S3协议目标的endpoint。

    s3.access_key

    使用S3协议目标的用户身份密钥。

    s3.secret_key

    使用S3协议目标的用户加密认证字符串。

    s3.region

    使用S3协议目标的Region。

    s3.session_token

    使用S3协议目标的用户临时会话token。若启用临时会话验证。

    use_path_style

    默认为false

    S3 SDK默认使用Virtual-hosted Style方式。

    但某些对象存储系统可能没开启或没支持Virtual-hosted Style方式的访问,您可以通过添加use_path_style参数来强制使用Path Style方式。

    说明

    URI目前支持三种方案(schema):http://https://s3://

    1. 如果使用http://https://,则会根据use_path_style参数来决定是否使用Path Style方式访问S3协议目标。

    2. 如果使用s3://,则会使用Virtual-hosted Style方式访问S3协议目标。

响应结果说明

导出命令为同步命令。命令返回即表示操作结束,并且会返回一行结果,来展示导出的执行结果。

  • 如果正常导出并返回,则结果如下:

    SELECT * FROM tbl1 LIMIT 10 INTO  outfile "file:///home/work/path/result_";
    +------------+-----------+----------+--------------------------------------------------------------------+
    | FileNumber | TotalRows | FileSize | URL                                                                |
    +------------+-----------+----------+--------------------------------------------------------------------+
    |          1 |         2 |        8 | file:///192.168.1.10/home/work/path/result_{fragment_instance_id}_ |
    +------------+-----------+----------+--------------------------------------------------------------------+
    1 row in set (0.05 sec)

    其中:

    参数名称

    参数说明

    FileNumber

    最终生成的文件个数。

    TotalRows

    结果集行数。

    FileSize

    导出文件总大小。单位字节。

    URL

    如果是导出到本地磁盘,则这里显示具体导出到哪个Compute Node。

  • 如果进行了并发导出,则会返回多行数据。

    +------------+-----------+----------+--------------------------------------------------------------------+
    | FileNumber | TotalRows | FileSize | URL                                                                |
    +------------+-----------+----------+--------------------------------------------------------------------+
    |          1 |         3 |        7 | file:///192.168.1.10/home/work/path/result_{fragment_instance_id}_ |
    |          1 |         2 |        4 | file:///192.168.1.11/home/work/path/result_{fragment_instance_id}_ |
    +------------+-----------+----------+--------------------------------------------------------------------+
    2 rows in set (2.218 sec)
  • 如果执行错误,则会返回错误信息,例如:

    SELECT * FROM tbl INTO OUTFILE ...
    ERROR 1064 (HY000): errCode = 2, detailMessage = ...

并发导出

默认情况下,查询结果集的导出是非并发的,也就是由单个BE节点,单线程导出的。因此导出时间和导出结果集大小正相关。

如果希望查询结果集可以并发导出,可开启并发导出以降低导出的时间。操作如下:

  1. 设置会话变量以开启并发导出:set enable_parallel_outfile = true;

  2. 验证查询是否可以并发导出。

    您开启并发导出后,如果想验证当前查询是否能进行并发导出,可以使用EXPLAIN分析查询导出语句。语法如下:

    EXPLAIN <select_into_outfile>;

    select_into_outfile为您要执行的SELECT INTO OUTFILE语句,具体语法,请参见语法

    对查询进行EXPLAIN后,SelectDB会返回该查询的规划,您需分析查询规划判断询是否可以并发导出。

    • RESULT FILE SINKPLAN FRAGMENT 1中:查询可并发导出。

      满足并发的查询,您可通be_instance_num * parallel_fragment_exec_instance_num计算并发导出查询结果集的并发度。

      • be_instance_numBE集群的节点数。

        • 计算资源为32核及以下的集群为单节点。

        • 计算资源为32核以上的集群,每32核为一个节点。

      • parallel_fragment_exec_instance_num是并发参数。

        您可通过以下语句查看此参数。

        SHOW variables LIKE  '% parallel_fragment_exec_instance_num%'; 

        通过以下语句设置此参数。

        SET  parallel_fragment_exec_instance_num = <parallel_fragment_exec_instance_num>;  
    • RESULT FILE SINKPLAN FRAGMENT 0中:查询不能并发导出。

      以下为一个SELECT INTO OUTFILE任务的查询规划,RESULT FILE SINKPLAN FRAGMENT 0中,该SELECT INTO OUTFILE可以并发导出。

      并发导出的规划示例:
      +-----------------------------------------------------------------------------+
      | Explain String                                                              |
      +-----------------------------------------------------------------------------+
      | PLAN FRAGMENT 0                                                             |
      |  OUTPUT EXPRS:<slot 2> | <slot 3> | <slot 4> | <slot 5>                     |
      |   PARTITION: UNPARTITIONED                                                  |
      |                                                                             |
      |   RESULT SINK                                                               |
      |                                                                             |
      |   1:EXCHANGE                                                                |
      |                                                                             |
      | PLAN FRAGMENT 1                                                             |
      |  OUTPUT EXPRS:`k1` + `k2`                                                   |
      |   PARTITION: HASH_PARTITIONED: `default_cluster:test`.`multi_tablet`.`k1`   |
      |                                                                             |
      |   RESULT FILE SINK                                                          |
      |   FILE PATH: s3://ml-bd-repo/bpit_test/outfile_1951_                        |
      |   STORAGE TYPE: S3                                                          |
      |                                                                             |
      |   0:OlapScanNode                                                            |
      |      TABLE: multi_tablet                                                    |
      +-----------------------------------------------------------------------------+
  3. 根据SELECT INTO OUTFILE的语法创建导出任务,导出数据。

使用示例

使用HDFS方式导出

使用HDFS方式导出。将简单查询结果导出到文件中,其中指定导出格式为CSV。示例如下。

说明

使用HDFS方式导出数据时,Hadoop集群是否已开启高可用,导致SELECT INTO OUTFILEPROPERTIES会有所不同。

Hadoop集群未开启高可用

-- fileSystem_port默认值为9000
SELECT * FROM tbl
INTO OUTFILE "hdfs://${host}:${fileSystem_port}/path/to/result_"
FORMAT AS CSV
PROPERTIES
(
    "fs.defaultFS" = "hdfs://ip:port",
    "hadoop.username" = "work"
);

Hadoop集群已开启高可用

--HA fileSystem_port默认值为8020
SELECT * FROM tbl
INTO OUTFILE "hdfs:///path/to/result_"
FORMAT AS CSV
PROPERTIES
(
'fs.defaultFS'='hdfs://hacluster/',
'dfs.nameservices'='hacluster',
'dfs.ha.namenodes.hacluster'='n1,n2',
'dfs.namenode.rpc-address.hacluster.n1'='192.168.0.1:8020',
'dfs.namenode.rpc-address.hacluster.n2'='192.168.0.2:8020',
'dfs.client.failover.proxy.provider.hacluster'='org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider'
);

生成的文件如果大小不超过1 GB,则为:result_0.csv。 如果大于1 GB,则可能为result_0.csv, result_1.csv, ...

使用S3协议导出到文件

UNION语句的查询结果导出到文件中。其中,存储系统指定为位于可用区cn-hangzhouOSS中的桶oss-bucket。指定导出格式为PARQUET(PARQUET格式无需指定列分割符),并且导出完成后,生成一个标识文件,示例如下。

SELECT k1 FROM tbl1 UNION SELECT k2 FROM tbl1
INTO OUTFILE "s3://oss-bucket/result_"
FORMAT AS PARQUET
PROPERTIES
(
    "s3.endpoint" = "oss-cn-hangzhou-internal.aliyuncs.com",
    "s3.access_key" = "****",
    "s3.secret_key" = "****",
    "s3.region" = "cn-hangzhou"
);
重要

使用S3协议导出数据时,对于不同云厂商提供的对象存储系统,URI都应该使用三种schema(http://,https://和 s3://)之一作为路径开头标志。否则将提示ERROR 1105 (HY000): errCode = 2, detailMessage = Unknown properties: [s3.region, s3.endpoint, s3.secret_key, s3.access_key]

使用S3协议并发导出到OSS

使用S3协议并发导出数据至OSS,示例如下。

SET enable_parallel_outfile = true;

SELECT k1 FROM tb1 LIMIT 1000
INTO outfile "s3://my_bucket/export/my_file_"
format AS csv
properties
(
    "s3.endpoint" = "oss-cn-hangzhou-internal.aliyuncs.com",
    "s3.access_key" = "****",
    "s3.secret_key" = "****",
    "s3.region" = "cn-hangzhou"
)

同样的数据结果集,但由于查询中包含对最终结果的排序处理(order by k1),所以这个查询即使开启并发导出的会话变量,也是无法并发导出的,示例如下。

SET enable_parallel_outfile = true;

SELECT k1 FROM tb1 ORDER BY k1 LIMIT 1000
INTO outfile "s3://my_bucket/export/my_file_"
format AS csv
properties
(
    "s3.endpoint" = "oss-cn-hangzhou-internal.aliyuncs.com",
    "s3.access_key" = "****",
    "s3.secret_key" = "****",
    "s3.region" = "cn-hangzhou"
)

数据类型映射

Parquet 和 ORC 文件格式都有各自的数据类型。SelectDB的导出功能能够自动将SelectDB的数据类型导出为Parquet/ORC文件格式所对应的数据类型。

  • SelectDB导出到ORC文件格式的数据类型映射:

    SelectDB Type

    Orc Type

    boolean

    boolean

    tinyint

    tinyint

    smallint

    smallint

    int

    int

    bigint

    bigint

    largeInt

    string

    date

    string

    datev2

    string

    datetime

    string

    datetimev2

    timestamp

    float

    float

    double

    double

    char / varchar / string

    string

    decimal

    decimal

    struct

    struct

    map

    map

    array

    array

  • 在将数据从SelectDB导出到Parquet文件格式时,会先将SelectDB内存中的数据转换为Arrow内存数据格式,然后由Arrow写出到Parquet文件格式。SelectDB数据类型到Arrow数据类的映射关系为:

    SelectDB Type

    Arrow Type

    boolean

    boolean

    tinyint

    int8

    smallint

    int16

    int

    int32

    bigint

    int64

    largeInt

    utf8

    date

    utf8

    datev2

    utf8

    datetime

    utf8

    datetimev2

    utf8

    float

    float32

    double

    float64

    char / varchar / string

    utf8

    decimal

    decimal128

    struct

    struct

    map

    map

    array

    list