在文件和表之间复制数据。
COPY table_name [(column_name [, ...])]
FROM {'filename' | PROGRAM 'command' | STDIN}
[ [ WITH ] ( option [, ...] ) ]
[ ON SEGMENT ]
COPY { table_name [(column_name [, ...])] | (query)}
TO {'filename' | PROGRAM 'command' | STDOUT}
[ [ WITH ] ( option [, ...] ) ]
[ ON SEGMENT ]
其中 option 可以是以下之一:
FORMAT format_name
OIDS [ boolean ]
FREEZE [ boolean ]
DELIMITER 'delimiter_character'
NULL 'null string'
HEADER [ boolean ]
QUOTE 'quote_character'
ESCAPE 'escape_character'
FORCE_QUOTE { ( column_name [, ...] ) | * }
FORCE_NOT_NULL ( column_name [, ...] )
FORCE_NULL ( column_name [, ...] )
ENCODING 'encoding_name'
FILL MISSING FIELDS
LOG ERRORS [ SEGMENT REJECT LIMIT count [ ROWS | PERCENT ] ]
IGNORE EXTERNAL PARTITIONS
COPY在 YMatrix 数据库表和标准文件系统文件之间移动数据。 COPY TO 将表的内容复制到一个文件(如果在 ON SEGMENT 上复制,则将基于 Segment ID 复制到多个文件), 而 COPY FROM 将数据从文件复制到表(将数据追加到表中已有的任何内容)。 COPY TO 还可以复制 SELECT 查询的结果。
如果指定了列列表,则 COPY 仅将指定列中的数据复制到文件中或从文件复制。 如果表中的任何列不在列列表中,则 COPY FROM 将为这些列插入默认值。
带有文件名的 COPY 指示 YMatrix 数据库 Master 主机直接从文件读取或写入文件。 该文件必须可供 Master 主机访问,并且必须从 Master 主机的角度指定名称。
当 COPY 与 ON SEGMENT 子句一起使用时, ON SEGMENT 导致 Segment 创建单独的面向 Segment 的文件,这些文件保留在 Segment 主机上。 ON SEGMENT 的 filename 参数采用字符串文字
使用复制表(DISTRIBUTED REPLICATED)作为源的 COPY TO 将创建一个文件,其中包含来自单个 Segment 的行,以便目标文件不包含重复的行。 将 COPY TO 与 ON SEGMENT 子句一起使用,并将复制表作为源,则在包含所有表行的 Segment 主机上创建目标文件。
ON SEGMENT 子句允许您将表数据复制到 Segment 主机上的文件中,以用于诸如在集群之间迁移数据或执行备份之类的操作。 可以使用诸如 gpfdist 之类的工具来恢复由 ON SEGMENT 子句创建的细分数据,这对于高速数据加载非常有用。
注意:建议仅对专业用户使用 ON SEGMENT 子句。 指定 PROGRAM 时,服务器将执行给定命令并从程序的标准输出中读取或写入程序的标准输入。 该命令必须从服务器的角度指定,并且可由 gpadmin 用户执行。
当指定 STDIN 或 STDOUT 时,数据将通过客户端和 Master 之间的连接进行传输。 STDIN 和 STDOUT 不能与 ON SEGMENT 子句一起使用。
如果使用 SEGMENT REJECT LIMIT,则 COPY FROM 操作将在单行错误隔离模式下运行。 在此版本中,单行错误隔离模式仅适用于输入文件中格式错误的行 - 例如,多余或缺失的属性,错误的数据类型的属性或无效的客户端编码序列。 约束错误(例如违反 NOT NULL,CHECK 或 UNIQUE 约束)仍将在“全有或全无”输入模式下处理。 用户可以指定可接受的错误行数(基于每个 segment),之后将终止整个 COPY FROM 操作,并且不会加载任何行。 错误行的计数是按 Segment 而不是整个加载操作计数的。 如果未达到每个 Segment 拒绝的限制,那么将加载所有不包含错误的行,并丢弃所有错误行。 要保留错误行以供进一步检查,请指定 LOG ERRORS 子句以捕获错误日志信息。 错误信息和该行存储在 YMatrix 内部数据库中。
成功完成后,COPY 命令将返回以下形式的命令标签,其中 count 是复制的行数:
COPY count
如果以单行错误隔离模式运行 COPY FROM 命令, 如果由于格式错误而未加载任何行,则将返回以下通知消息,其中 count 是拒绝的行数:
NOTICE: Rejected count badly formatted rows.
table_name
column_name
query
filename
PROGRAM 'command'
STDIN
STDOUT
boolean
FORMAT
OIDS
FREEZE
DELIMITER
NULL
HEADER
QUOTE
ESCAPE
FORCE_QUOTE
FORCE_NOT_NULL
FORCE_NULL
ENCODING
ON SEGMENT
COPY table [TO|FROM] '<SEG_DATA_DIR>/gpdumpname<SEGID>_suffix' ON SEGMENT;
NEWLINE
CSV
FILL MISSING FIELDS
LOG ERRORS
SEGMENT REJECT LIMIT count [ROWS | PERCENT]
IGNORE EXTERNAL PARTITIONS
COPY 只能与表一起使用,而不能与外部表或视图一起使用。 但是,您可以执行 COPY (SELECT * FROM viewname) TO ...
当指定 ON SEGMENT 子句时, COPY 命令不支持在 COPY TO 命令中指定 SELECT 语句。 例如,不支持此命令。
COPY (SELECT * FROM testtbl) TO '/tmp/mytst<SEGID>' ON SEGMENT
COPY 仅处理特定名称的表,它不会在子表之间复制数据。 因此,例如 COPY table TO 显示的数据与 SELECT FROM ONLY table 相同。 但是 COPY (SELECT FROM table) TO ...可用于转储继承层次结构中的所有数据。
同样,要从具有作为外部表的叶子分区的分区表中复制数据,请使用 SQL 查询来复制数据。 例如,如果表 my_sales 包含带有作为外部表的叶子分区, 则此命令 COPY my_sales TO stdout 返回错误。 此命令将数据发送到 stdout:
BINARY 关键字使所有数据以二进制格式而不是文本形式存储/读取。 它比普通的文本模式要快一些,但是二进制格式的文件在计算机体系结构和 YMatrix 数据库版本之间的移植性较差。 另外,如果数据为二进制格式,则不能以单行错误隔离模式运行 COPY FROM。
您必须对通过 COPY TO 读取的表具有 SELECT 特权, 并且对于通过 COPY FROM 将值插入其中的表具有插入特权。 在命令中列出的列上具有列特权就足够了。
COPY 命令中命名的文件由数据库服务器而不是客户端应用程序直接读取或写入。 因此,它们必须位于 YMatrix 数据库 Master 主机上(而不是客户端)或可被其访问。 YMatrix 数据库系统用户(服务器运行时使用的用户 ID),而不是客户端,必须可以访问它们并对其进行读写。 COPY 命名文件只允许数据库超级用户使用,因为它允许读取或写入服务器有权访问的任何文件。
COPY FROM 将调用任何触发器并检查目标表上的约束。 但是,它不会调用重写规则。 请注意,在此版本中,不针对单行错误隔离模式评估违反约束的情况。
COPY 输入和输出受 DateStyle 影响。 为了确保可移植到可能使用非默认 DateStyle 设置的其他 YMatrix 数据库安装, 在使用 COPY TO 之前,应将 DateStyle 设置为 ISO。 避免转储 IntervalStyle 设置为 sql_standard 的数据也是一个好主意, 因为对于 IntervalStyle 不同设置的服务器可能会误解负间隔值。
输入数据将根据 ENCODING 选项或当前客户端编码进行解释, 而输出数据将以 ENCODING 或当前客户端编码进行编码, 即使数据没有通过客户端,而是由服务器直接从文件读取或写入文件 。
在文本模式下从文件复制 XML 数据时,服务器配置参数 xmloption 会影响对复制的 XML 数据的验证。 如果该值为 content(默认值),则将 XML 数据验证为 XML 内容片段。 如果参数值为 document,则将 XML 数据验证为 XML 文档。 如果 XML 数据无效,则 COPY 返回错误。
默认情况下,COPY 在第一个错误时停止操作。 如果是 COPY TO,这应该不会导致问题,但是目标表已经在 COPY FROM 中接收到了较早的行。 这些行将不可见或不可访问,但仍会占用磁盘空间。 如果故障在大型 COPY FROM 操作中发生,则可能会浪费大量磁盘空间。 您可能希望调用 VACUUM 来恢复浪费的空间。 另一种选择是使用单行错误隔离模式来过滤掉错误行,同时仍然加载正确的行。
运行 COPY FROM...ON SEGMENT 命令时, 服务器配置参数 gp_enable_segment_copy_checking 控制在将数据复制到表中时是否检查表分发策略(来自表 DISTRIBUTED 子句)。 默认设置为检查分发策略。 如果数据行违反了 Segment 实例的分配策略,则返回错误。
COPY TO...ON SEGMENT 命令生成的表数据可用于通过 COPY FROM...ON SEGMENT 恢复表数据。 但是,使用 COPY TO 命令生成文件时,将根据表分发策略来分发恢复到 Segment 的数据。 如果尝试还原表数据并且在运行 COPY FROM...ON SEGMENT 之后更改了表分发策略,则 COPY 命令可能会返回表分发策略错误。
Note: 如果运行 COPY FROM...ON SEGMENT, 并且服务器配置参数 gp_enable_segment_copy_checking 为 false,则可能需要手动重新分配表数据。 请参阅 ALTER TABLE 子句 WITH REORGANIZE。 当您指定 LOG ERRORS 子句时,YMatrix 数据库将捕获读取外部表数据时发生的错误。 您可以查看和管理捕获的错误日志数据。
SELECT * from gp_read_error_log('ext_expenses');
SELECT gp_truncate_error_log('ext_expenses');
当不是超级用户的 YMatrix 数据库用户运行COPY命令时,该命令可以由资源队列控制。 资源队列必须配置有ACTIVE_STATEMENTS参数,该参数指定分配给该队列的角色可以执行的查询数量的最大限制。 YMatrix 数据库不会将成本值或内存值应用于 COPY 命令,仅具有成本或内存限制的资源队列不会影响 COPY 命令的运行。
非超级用户只能运行以下类型的 COPY 命令:
COPY 支持的文件格式。
使用文本格式时,读取或写入的数据是一个文本文件,每行一行。 行中的列由 delimiter_character 分隔(默认为制表符)。 列值本身是由每个属性的数据类型的输出函数生成的字符串,或输入函数可接受的字符串。 使用空字符串代替空列。 如果输入文件的任何行包含的列比预期的多或少,则 COPY FROM 将引发错误。 如果指定了 OIDS,则将 OID 读取或写入为用户数据列之前的第一列。
数据文件具有两个保留字符,它们对于 COPY 具有特殊含义:
如果数据包含这些字符中的任何一个,则必须转义该字符,以便 COPY 将其视为数据而不是字段分隔符或新行。
默认情况下,对于文本格式的文件,转义字符是 \(反斜杠),对于 csv 格式的文件,转义字符是 "(双引号)。 如果要使用其他转义字符,则可以使用 ESCAPE AS 子句来实现。 确保选择一个在数据文件中任何地方都没有使用的转义字符作为实际数据值, 也可以通过使用 ESCAPE 'OFF' 来禁用文本格式文件中的转义。
例如,假设您有一个包含三列的表,并且想使用 COPY 加载以下三个字段。
您指定的 delimiter_character 为 |(竖线字符),而您指定的转义字符为 *(星号)。 数据文件中的格式化行如下所示:
percentage sign = % | vertical bar = *| | backslash = \
请注意,如何使用星号字符(*)对作为数据一部分的管道字符进行转义。 另请注意,由于我们使用的是替代转义字符,因此我们不需要转义反斜杠。
如果以下字符作为列值的一部分出现,则必须在其后加上转义字符:转义字符本身,换行符,回车符和当前定界符。 您可以使用 ESCAPE AS 子句指定其他转义字符。
此格式选项用于导入和导出许多其他程序(例如电子表格)使用的逗号分隔值(CSV)文件格式。 它生成并识别常见的 CSV 转义机制,而不是 YMatrix 数据库标准文本格式使用的转义规则。
每个记录中的值由 DELIMITER 字符分隔。 如果值包含定界符,QUOTE 字符,ESCAPE 字符(默认情况下为双引号), NULL 字符串,回车符或换行符,则整个值将以 QUOTE 字符作为前缀和后缀。 在特定列中输出非 NULL 值时,也可以使用 FORCE_QUOTE 强制使用引号。
CSV 格式没有区分 NULL 值和空字符串的标准方法。 YMatrix 数据库 COPY 通过引用进行处理。 输出 NULL 作为 NULL 参数字符串, 并且不加引号,而与 NULL 字符串匹配的非 NULL 值被加引号。 例如,使用默认设置,将 NULL 写入未加引号的空字符串,而将空字符串数据值写入双引号("")。 读取值遵循类似的规则。 您可以使用 FORCE_NOT_NULL 来防止对特定列进行 NULL 输入比较。
由于反斜杠不是 CSV 格式的特殊字符,因此 .(数据结尾标记)也可能会显示为数据值。 为避免任何误解,使用 . 在行上显示为单独条目的数据值会在输出上自动加引号,并且在输入上(如果加引号)也不会被解释为数据结束标记。 如果要加载的文件是由另一个应用程序创建的,该文件具有未加引号的单列并且可能具有 . 值,则可能需要在输入文件中使用该值。
注意:在 CSV 格式中,所有字符均有效。 用引号括起来的空格或除 DELIMITER 以外的任何字符都将包含这些字符。 如果从空白行填充到固定宽度的 CSV 行的系统中导入数据,则可能会导致错误。 如果出现这种情况,在将数据导入 YMatrix 数据库之前,可能需要预处理 CSV 文件以删除尾随空白。
CSV 格式将识别并生成带有引用值的 CSV 文件,这些值包含嵌入式回车符和换行符。 因此,与文本格式的文件相比,文件并非严格限于每行一行
注意:许多程序会生成奇怪的(有时是错误的)CSV 文件,因此文件格式更像是约定俗成的标准文件。 因此,您可能会遇到一些无法使用此机制导入的文件,并且 COPY 可能会生成其他程序无法处理的文件。
二进制格式选项使所有数据以二进制格式而不是文本形式存储/读取。 它比文本和 CSV 格式要快一些,但是二进制格式的文件在计算机体系结构和 YMatrix 数据库版本之间的可移植性较差。 同样,二进制格式是非常特定于数据类型的。 例如,即使在文本格式下也可以正常工作,但从 smallint 列输出二进制数据并将其读入整数列将不起作用。
二进制文件格式由文件头,包含行数据的零个或多个元组和文件尾部组成。 文件头和数据按网络字节序排列。
使用竖线(|)作为字段定界符,将表复制到客户端:
COPY country TO STDOUT (DELIMITER '|');
将数据从文件复制到 country 表:
COPY country FROM '/home/usr1/sql/country_data';
仅将名称以 'A' 开头的国家复制到文件中:
COPY (SELECT * FROM country WHERE country_name LIKE 'A%') TO
'/home/usr1/sql/a_list_countries.copy';
使用单行错误隔离模式将数据从文件复制到 sales 表中并记录错误:
COPY sales FROM '/home/usr1/sql/sales_data' LOG ERRORS
SEGMENT REJECT LIMIT 10 ROWS;
若要复制 Segment 数据供以后使用,请使用 ON SEGMENT 子句。 COPY TO ON SEGMENT 命令的使用形式如下:
COPY table TO '<SEG_DATA_DIR>/gpdumpname<SEGID>_suffix' ON SEGMENT;
\<SEGID> 是必需的。 但是,您可以用绝对路径替换路径中的 \<SEG_DATA_DIR> 字符串文字。
将字符串文字 \<SEG_DATA_DIR> 和 \<SEGID> 传递给 COPY 时, 运行操作时 COPY 将填充适当的值。
例如,如果您的 mytable 包含以下 Segment 和 Mirror:
contentid | dbid | file segment location
0 | 1 | /home/usr1/data1/gpsegdir0
0 | 3 | /home/usr1/data_mirror1/gpsegdir0
1 | 4 | /home/usr1/data2/gpsegdir1
1 | 2 | /home/usr1/data_mirror2/gpsegdir1
运行命令:
COPY mytable TO '<SEG_DATA_DIR>/gpbackup<SEGID>.txt' ON SEGMENT;
将会产生如下行:
/home/usr1/data1/gpsegdir0/gpbackup0.txt
/home/usr1/data2/gpsegdir1/gpbackup1.txt
第一列中的内容 ID 是插入文件路径中的标识符(例如,上面的 gpsegdir0 / gpbackup0.txt)。 文件是在 Segment 上而不是在 Master 上创建的,就像在标准 COPY 操作中那样。 使用 ON SEGMENT 复制时,不会为 Mirror 创建任何数据文件。
如果指定了绝对路径,而不是 \<SEG_DATA_DIR>,例如在语句中
COPY mytable TO '/tmp/gpdir/gpbackup_<SEGID>.txt' ON SEGMENT;
文件将放置在每个 Segment 的 /tmp/gpdir 中。 如果需要重新分发,gpfdist 工具还可用于使用 ON SEGMENT 选项还原由 COPY TO 生成的数据文件。 注意:可以使用诸如 gpfdist 之类的工具来还原数据。 备份/还原工具不适用于使用 COPY TO ON SEGMENT 手动生成的文件。 本示例从 lineitem 表复制数据,并使用 PROGRAM 子句使用 cat 实用程序将数据添加到 /tmp/lineitem_program.csv 文件。 该文件放置在 YMatrix 数据库 Master 上。
COPY LINEITEM TO PROGRAM 'cat > /tmp/lineitem.csv' CSV;
本示例使用 PROGRAM 和 ON SEGMENT 子句将数据复制到 Segment 主机上的文件中。 在 Segment 主机上,COPY 命令将 \<SEGID> 替换为 Segment content ID,以为 Segment 主机上的每个 Segment 实例创建一个文件。
COPY LINEITEM TO PROGRAM 'cat > /tmp/lineitem_program<SEGID>.csv' ON SEGMENT CSV;
本示例使用 PROGRAM 和 ON SEGMENT 子句从 Segment 主机上的文件复制数据。 从文件复制数据时,COPY 命令用 Segment content ID 替换\<SEGID>。 在 Segment 主机上,每个 Segment 实例必须有一个文件,其中文件名包含 Segment 主机上的 Segment content ID。
COPY LINEITEM_4 FROM PROGRAM 'cat /tmp/lineitem_program<SEGID>.csv' ON SEGMENT CSV;
SQL 标准中没有 COPY 语句。
在较早版本的 YMatrix 数据库中使用了以下语法,仍然被支持:
COPY table_name [(column_name [, ...])] FROM
{'filename' | PROGRAM 'command' | STDIN}
[ [WITH]
[ON SEGMENT]
[BINARY]
[OIDS]
[HEADER]
[DELIMITER [ AS ] 'delimiter_character']
[NULL [ AS ] 'null string']
[ESCAPE [ AS ] 'escape' | 'OFF']
[NEWLINE [ AS ] 'LF' | 'CR' | 'CRLF']
[CSV [QUOTE [ AS ] 'quote']
[FORCE NOT NULL column_name [, ...]]
[FILL MISSING FIELDS]
[[LOG ERRORS]
SEGMENT REJECT LIMIT count [ROWS | PERCENT] ]
COPY { table_name [(column_name [, ...])] | (query)} TO {'filename' | PROGRAM 'command' | STDOUT}
[ [WITH]
[ON SEGMENT]
[BINARY]
[OIDS]
[HEADER]
[DELIMITER [ AS ] 'delimiter_character']
[NULL [ AS ] 'null string']
[ESCAPE [ AS ] 'escape' | 'OFF']
[CSV [QUOTE [ AS ] 'quote']
[FORCE QUOTE column_name [, ...]] | * ]
[IGNORE EXTERNAL PARTITIONS ]
请注意,在此语法中,BINARY 和 CSV 被视为独立的关键字,而不是 FORMAT 选项的参数。