云服务器内容精选

  • 概述 通过外表导出数据:通过GDS外表设置的导出模式、导出数据格式等信息来指定待导出的数据文件,利用多DN并行的方式,将数据从数据库导出到数据文件中,从而提高整体导出性能。不支持直接导出文件到HDFS文件系统。 CN只负责任务的规划及下发,把数据导出的工作交给了DN,释放了CN的资源,使其有能力处理外部请求。 通过让各个DN都参与数据导出,充分利用各个设备的计算能力及网络带宽。 图1 通过外表导出数据
  • 导出流程 图2 并行导出流程 表1 流程说明 流程 说明 子任务 规划导出数据。 根据所选模式,准备需要导出的数据并规划导出路径。 详细内容请参见规划导出数据 - 启动GDS。 若规划的导出模式为Remote模式,需在数据服务器上安装配置并启动GDS。 详细内容请参见安装配置和启动GDS。 - 创建外表。 创建外表用于帮助GDS指定导出的数据文件。外表中保存了导出数据文件的位置、文件格式、编码格式、数据间的分隔符等信息。 详细内容请参见创建GDS外表。 - 执行导出数据。 在创建好外表后,通过INSERT语句,将数据快速、高效地导出到数据文件中。 详细内容请参见执行导出数据。 - 停止GDS。 数据导出完成后,停止GDS。 详细请参见停止GDS。 -
  • 相关概念 数据文件:存储有数据的TEXT、 CS V或FIXED文件。文件中保存的是从 GaussDB (DWS)数据库导出的数据。 外表:用于规划导出数据文件的数据文件格式、存放位置、编码格式等信息。 GDS:数据服务工具。在导出数据时,需要将此工具部署到数据文件所在的服务器上,使DN可以通过该工具导出数据。 表:数据库中的表,包括行存表和列存表。数据文件中的数据从这些表中导出。 Remote导出模式:将集群中的业务数据导出到集群之外的主机上。
  • 导入流程 图3 GDS并行导入流程 表1 流程说明 流程 说明 准备源数据。 准备需要导入数据库的源数据文件,并上传至数据服务器。 详细内容请参见准备源数据。 启动GDS。 在数据服务器上安装配置并启动GDS。 详细内容请参见安装配置和启动GDS。 创建外表。 创建外表用于识别数据源文件中的数据。外表中保存了数据源文件的位置、文件格式、存放位置、编码格式、数据间的分隔符等信息。 详细内容请参见创建GDS外表。 执行导入数据。 在创建好外表后,通过INSERT语句,将数据快速、高效地导入到目标表中。详细内容请参见执行导入数据。 处理错误表。 在数据并行导入发生错误时,请根据具体的错误信息进行处理,以保证导入数据的完整性。 详细内容请参见处理导入错误。 优化查询效率。 导入数据后,通过ANALYZE语句生成表统计信息。ANALYZE语句会将统计结果自动存储在系统表PG_STATISTIC中。执行计划生成器会使用这些统计数据,以生成最有效的查询执行计划。 停止GDS 待数据导入完成后,登录每台数据服务器,分别停止GDS。 GDS的停止请参见停止GDS。
  • GDS并发导入 数据量大,数据存储在多个服务器上时,在每个数据服务器上安装配置、启动GDS后,各服务器上的数据可以并行入库。如图2所示。 图2 多数据服务器并行导入 GDS进程数目不能超过DN数目。如果超过,会出现一个DN连接多个GDS进程的情形,可能会导致部分GDS异常运行。 数据存储在一台数据服务器上时,如果GaussDB(DWS)及数据服务器上的I/O资源均还有可利用空间时,可以采用GDS多线程来支持并发导入。 GDS是根据导入事务并发数来决定服务运行线程数的,也就是说即使启动GDS时设置了多线程,也并不会加速单个导入事务。未做过人为事务处理时,一条INSERT语句就是一个导入事务。 综上,多线程的使用场景如下: 多表并发导入时,采用多线程充分利用资源及提升并发导入效率。 对数据量大的某一事实表的导入进行提速。 将该事实表对应的数据拆分为多个数据文件,通过多外表同时入库的方式实现多线程并发导入。注意需确保每个外表所能读取的数据文件不重复。
  • 概述 并行导入将存储在服务器普通文件系统中的数据导入到GaussDB(DWS)数据库中。暂时不支持将存储在HDFS文件系统上的数据导入GaussDB(DWS)。 并行导入功能通过外表设置的导入策略、导入数据格式等信息来识别数据源文件,利用多DN并行的方式,将数据从数据源文件导入到数据库中,从而提高整体导入性能。如图1所示: CN只负责任务的规划及下发,把数据导入的工作交给了DN,释放了CN的资源,使其有能力处理其他外部请求。 所有DN都参与数据导入,这样可以充分利用各设备的计算能力及网络带宽,提升导入效率。 外表灵活的OPTION设置,有利于在数据入库前对数据做预处理,例如非法字符替换、容错处理等。 图1 数据并行导入示意图 上图中所涉及的相关概念说明如下: CN(Coordinator):GaussDB(DWS)协调节点。在导入场景下,接收到应用或客户端的导入SQL指令后,负责任务的规划及下发到DN。 DN(Datanode):GaussDB(DWS)数据节点。接收CN下发的导入任务,将数据源文件中的数据通过外表写入数据库目标表中。 数据源文件:存有数据的文件。文件中保存的是待导入数据库的数据。 数据服务器:数据源文件所在的服务器称为数据服务器。基于安全考虑,建议数据服务器和GaussDB(DWS)集群处于同一内网。 外表Foreign Table:用于识别数据源文件的位置、文件格式、存放位置、编码格式、数据间的分隔符等信息。是关联数据文件与数据库实表(目标表)的对象。 目标表:数据库中的实表。数据源文件中的数据最终导入到这些表中存储,包括行存表和列存表。
  • 教程指引 本教程旨在演示使用GDS(Gauss Data Service)工具将远端服务器上的数据导入GaussDB中的办法,帮助您学习如何通过GDS进行数据导入的方法。 在本教程中,您将: 生成本教程需要使用的CSV格式的数据源文件。 将数据源文件上传到数据服务器。 创建外表,用于对接GDS和GaussDB,及将数据服务器上的数据引流到GaussDB集群中。 启动GaussDB并创建数据库表后,将数据导入到表中。 根据错误表中的提示诊断加载错误并更正这些错误。 父主题: 教程:使用GDS从远端服务器导入数据
  • 处理数据导入错误 根据获取的错误信息,请对照下表,处理数据导入错误。 表2 处理数据导入错误 错误信息 原因 解决办法 missing data for column "r_reason_desc" 数据源文件中的列数比外表定义的列数少。 对于TEXT格式的数据源文件,由于转义字符(\)导致delimiter(分隔符)错位或者quote(引号字符)错位造成的错误。 示例:目标表存在3列字段,导入的数据如下所示。由于存在转义字符“\”,分隔符“|”被转义为第二个字段的字段值,导致第三个字段值缺失。 BE|Belgium\|1 由于列数少导致的报错,选择下列办法解决: 在数据源文件中,增加列“r_reason_desc”的字段值。 在创建外表时,将参数“fill_missing_fields”设置为“on”。即在导入过程中,若数据源文件中一行数据的最后一个字段缺失,则把最后一个字段的值设置为NULL,不报错。 对由于转义字符导致的错误,需检查报错的行中是否含有转义字符(\)。若存在,建议在创建外表时,将参数“noescaping”(是否不对'\'和后面的字符进行转义)设置为true。 extra data after last expected column 数据源文件中的列数比外表定义的列数多。 在数据源文件中,删除多余的字段值。 在创建外表时,将参数“ignore_extra_data”设置为“on”。即在导入过程中,若数据源文件比外表定义的列数多,则忽略行尾多出来的列。 invalid input syntax for type numeric: "a" 数据类型错误。 在数据源文件中,修改输入字段的数据类型。根据此错误信息,请将输入的数据类型修改为numeric。 null value in column "staff_id" violates not-null constraint 非空约束。 在数据源文件中,增加非空字段信息。根据此错误信息,请增加“staff_id”列的值。 duplicate key value violates unique constraint "reg_id_pk" 唯一约束。 删除数据源文件中重复的行。 通过设置关键字“DISTINCT”,从SELECT结果集中删除重复的行,保证导入的每一行都是唯一的。 1 INSERT INTO reasons SELECT DISTINCT * FROM foreign_tpcds_reasons; value too long for type character varying(16) 字段值长度超过限制。 在数据源文件中,修改字段值长度。根据此错误信息,字段值长度限制为VARCHAR2(16)。
  • 安装和启动GDS 登录GaussDB(DWS)管理控制台。 在左侧导航栏中,单击“连接客户端”。 在 “gsql 命令行客户端”的下拉列表中,选择对应版本的GaussDB(DWS)客户端。 请根据集群版本和安装客户端的操作系统,选择对应版本。 客户端CPU架构要和集群一致,如果集群是X86规格,则也应该选择X86客户端。 单击“下载”。 将GDS工具包上传至ECS的/opt目录中,本例以上传Euler Kunpeng版本的工具包为例。 在工具包所在目录下,解压工具包。 1 2 cd /opt/ unzip dws_client_8.1.x_euler_kunpeng_x64.zip 创建用户gds_user及其所属的用户组gdsgrp。此用户用于启动GDS,且需要拥有读取数据源文件目录的权限。 1 2 groupadd gdsgrp useradd -g gdsgrp gds_user 修改工具包以及数据源文件目录属主为创建的用户gds_user及其所属的用户组gdsgrp。 1 2 3 chown -R gds_user:gdsgrp /opt/ chown -R gds_user:gdsgrp /data1 chown -R gds_user:gdsgrp /data2 切换到gds_user用户。 1 su - gds_user 执行环境依赖脚本(仅8.1.x版本适用)。 1 2 cd /opt/gds/bin source gds_env 启动GDS。 1 2 3 4 /opt/gds/bin/gds -d /data1/script/tpch-kit/tpch1000X -p 192.168.0.90:5000 -H 192.168.0.0/24 -l /opt/gds/gds01_log.txt -D #TPC-H使用 /opt/gds/bin/gds -d /data2/script/tpch-kit/tpch1000X -p 192.168.0.90:5001 -H 192.168.0.0/24 -l /opt/gds/gds02_log.txt -D #TPC-H使用 /opt/gds/bin/gds -d /data1/script/tpcds-kit/tpcds1000X/ -p 192.168.0.90:5002 -H 192.168.0.0/24 -l /opt/gds/gds03_log.txt -D #TPC-DS使用 /opt/gds/bin/gds -d /data2/script/tpcds-kit/tpcds1000X/ -p 192.168.0.90:5003 -H 192.168.0.0/24 -l /opt/gds/gds04_log.txt -D #TPC-DS使用 命令中的斜体部分请根据实际填写,如果数据分片存放至多个数据盘目录,需要启动对应目录数量的GDS。 如果TPC-H和TPC-DS数据同时测试,需要启动以上4个GDS,如果只测试TPC-DS或TPC-H数据,请根据后面的“#xxx”备注启动对应的GDS服务即可。 -d dir:保存有待导入数据的数据文件所在目录。 -p ip:port:GDS监听IP和监听端口。IP替换为ECS的内网IP,确保GaussDB(DWS)能通过此IP与GDS的通讯;端口对于TPC-H取5000、5001,对于TPC-DS取5002、5003。 -H address_string:允许哪些主机连接和使用GDS服务。参数需为CIDR格式。此地址配置成GaussDB(DWS)的集群内网网段(即GDS所在的ECS与GaussDB(DWS)在同一个VPC下,以内网通讯即可),例如192.168.0.0/24。 -l log_file:存放GDS的日志文件路径及文件名。 -D:后台运行GDS。仅支持Linux操作系统下使用。
  • 实例管理概述 数据迁移功能采用独立集群的方式为用户提供安全可靠的数据迁移服务,各集群之间相互隔离,不可互相访问。其中实例管理通过购买GDS-Kafka实例帮助用户创建、管理集群。GDS-Kafka的工作方式是从Kafka中消耗数据并缓存,当达到设置好的时间或数据量之后,通过COPY写入GaussDB(DWS)临时表,再从临时表进行插入或更新操作。 Kafka的消息生产端必须按照一定的格式要求进行数据生产,其中消息格式由“kafka.source.event.type”配置参数指定。当前支持的消息格式详见GDS-Kafka支持的消息格式。 GDS-Kafka支持直接insert(仅限无主键表)和merge覆盖更新两种入库模式,您可以根据DWS目标表的类型进行灵活配置,直接insert模式由于不涉及更新在性能上要更优一些。其中入库模式由“app.insert.directly”配置参数和有无主键共同决定,详见GDS-Kafka入库模式。 GDS-kafka只支持目标表表名和字段全小写。 GDS-Kafka的删除是根据扩展字段中的pos进行历史删除,如果入库数据中有delete操作,则必须使用扩展字段。
  • GDS-Kafka入库模式 GDS-Kafka的数据入库都是先将数据copy至临时表,然后再根据客户的使用场景以及目标表有无主键进行merge或者insert,详见下表: 表3 GDS-Kafka入库模式 入库操作 app.insert.directly 是否主键表 入库模式 insert true(仅支持无主键表) 否 使用insert select从临时表写入到目标表。 false 是 根据主键从临时表merge到目标表。 否 使用insert select从临时表写入到目标表。 delete true(仅支持无主键表) 否 使用insert select从临时表写入到目标表。 false 说明: delete操作支持标记删除,通过配置app.del.flag参数可以指定删除标记字段,如果配置了标记删除字段,则会通过将删除字段设置为1来标记删除的记录。 是 如果设置了delflag字段,则会根据主键进行匹配merge,如果匹配到主键并且目标表中记录的pos小于临时表记录的pos,则会将delflag字段置为1,否则将插入一条新的记录。 如果没有设置delflag字段,则会根据主键进行匹配,如果匹配到记录并且目标表中记录的pos小于临时表记录的pos,则会将目标表中匹配到的记录删除。 否 如果设置了delflag字段,则会使用临时表中记录的所有字段与目标表进行匹配merge,如果匹配到记录并且目标表中记录的pos小于临时表记录的pos,则会将delflag字段值置为1,否则将插入一条新的记录。 如果没有设置delflag字段,则会使用临时表中记录的所有字段与目标表进行匹配,如果匹配到记录并且目标表中记录的pos小于临时表记录的pos,则会将目标表中匹配到的记录删除。 update true(仅支持无主键表) 否 使用insert+select从临时表写入到目标表。 false 说明: update操作会被拆分,将before或者beforeImage中的消息拆分为delete操作,将after或者afterImage中的消息拆分为insert操作,然后再按照insert和delete的行为进行入库处理。 是 相当于有主键表的insert+delete操作。 否 相当于无主键表的insert+delete操作。
  • 步骤5:分析和处理错误表中的错误信息 对数据导入过程中出现的数据格式错误信息进行处理,若没有错误信息,此步骤可跳过。 查询错误信息。 1 postgres=# SELECT * FROM product_info_err ; 处理错误表中的错误信息。 按照本教程的示例操作,错误表中应该无错误信息。 您也可以将步骤2:在数据服务器上安装配置和启动GDS一节所建外表中的FILL_MISSING_FIELDS和IGNORE_EXTRA_DATA改为 'false'后,重新进行数据导入并查询错误表。此时,您将看到因如下原因带来的数据格式错误信息记录: 源数据文件product_info2.csv中第2条记录的最后一个字段“product_comment_content”缺失。 源数据文件product_info2.csv中第3条记录比外表定义列数多。 更多关于错误表及错误信息的处理请参见处理错误表。 父主题: 教程:使用GDS从远端服务器导入数据
  • 步骤6:优化导入数据的查询性能 在数据导入完成后,执行ANALYZE语句生成表统计信息。执行计划生成器会使用这些统计数据,以生成最有效的查询执行计划。 如果导入过程中,进行了大量的更新或删除行时,应运行VACUUM FULL命令,然后运行ANALYZE命令。大量的更新和删除操作,会产生大量的磁盘页面碎片,从而逐渐降低查询的效率。VACUUM FULL可以将磁盘页面碎片恢复并交还操作系统。 对表product_info执行VACUUM FULL。 1 postgres=# VACUUM FULL product_info; VACUUM 更新表product_info的统计信息。 1 postgres=# ANALYZE product_info; ANALYZE 父主题: 教程:使用GDS从远端服务器导入数据
  • 集群间不落地数据导入 启动GDS。(如果已经启动跳过此步骤) gds -d /***/gds_data/ -D -p GDS_IP:GDS_PORT -l /***/gds_log/aa.log -H 0/0 -t 10 -D 如果需要设置管道文件的超时时间,则使用--pipe-timeout参数设置。 源数据库数据导出。 登录目标数据库创建内表,并写入数据。 CREATE TABLE test_pipe( id integer not null, sex text not null, name text ); INSERT INTO test_pipe values(1,2,'11111111111111'); INSERT INTO test_pipe values(2,2,'11111111111111'); INSERT INTO test_pipe values(3,2,'11111111111111'); INSERT INTO test_pipe values(4,2,'11111111111111'); INSERT INTO test_pipe values(5,2,'11111111111111'); 创建只写外表。 CREATE FOREIGN TABLE foreign_test_pipe( id integer not null, age text not null, name text ) SERVER gsmpp_server OPTIONS (LOCATION 'gsfs://GDS_IP:GDS_PORT/', FORMAT 'text', DELIMITER ',', NULL '', EOL '0x0a' ,file_type 'pipe') WRITE ONLY; 导入语句,此时语句会阻塞。 INSERT INTO foreign_test_pipe SELECT * FROM test_pipe; 目标集群导入数据。 创建内表。 CREATE TABLE test_pipe (id integer not null, sex text not null, name text); 创建只读外表。 CREATE FOREIGN TABLE foreign_test_pipe(like test_pipe) SERVER gsmpp_server OPTIONS (LOCATION 'gsfs://GDS_IP:GDS_PORT/', FORMAT 'text', DELIMITER ',', NULL '', EOL '0x0a' , file_type 'pipe', auto_create_pipe 'false'); 执行导入语句: INSERT INTO test_pipe SELECT * FROM foreign_test_pipe; 查看目标集群导入语句返回的结果: SELECT * FROM test_pipe; id | sex | name ----+-----+---------------- 3 | 2 | 11111111111111 6 | 2 | 11111111111111 7 | 2 | 11111111111111 1 | 2 | 11111111111111 2 | 2 | 11111111111111 4 | 2 | 11111111111111 5 | 2 | 11111111111111 8 | 2 | 11111111111111 9 | 2 | 11111111111111 (9 rows) GDS默认导出或者导入的管道文件命名规则为:“数据库名_模式名_外表名.pipe”,因此默认需要目标集群与源集群的数据库名及模式名保持一致。如果数据库或模式不一致,则可以在location的url中指定相同的管道文件。 示例: 只写外表指定管道名。 CREATE FOREIGN TABLE foreign_test_pipe(id integer not null, age text not null, name text) SERVER gsmpp_server OPTIONS (LOCATION 'gsfs://GDS_IP:GDS_PORT/foreign_test_pipe.pipe', FORMAT 'text', DELIMITER ',', NULL '', EOL '0x0a' ,file_type 'pipe') WRITE ONLY; 只读外表指定管道名。 CREATE FOREIGN TABLE foreign_test_pipe(like test_pipe) SERVER gsmpp_server OPTIONS (LOCATION 'gsfs://GDS_IP:GDS_PORT/foreign_test_pipe.pipe', FORMAT 'text', DELIMITER ',', NULL '', EOL '0x0a' ,file_type 'pipe',auto_create_pipe 'false');
  • 任务示例 示例1:将表reason的数据通过外表foreign_tpcds_reasons导出到数据文件中。 1 INSERT INTO foreign_tpcds_reasons SELECT * FROM tpcds.reason; 示例2:通过条件过滤(r_reason_sk =1),向数据文件中导出部分数据。 1 INSERT INTO foreign_tpcds_reasons SELECT * FROM tpcds.reason WHERE r_reason_sk=1; 示例3:对于特殊的数据类型如RAW类型,在导出之后是一个二进制文本,导入工具无法识别。需使用RAWTOHEX()函数将其转换为16进制文本导出。 1 INSERT INTO foreign_tpcds_reasons SELECT RAWTOHEX(c) FROM tpcds.reason;