更新时间:2024-06-07 GMT+08:00

gs_loader

概述

  • gs_loader工具用于进行数据导入。gs_loader将控制文件支持的语法转换为\COPY语法,然后利用已有的\COPY功能,做主要数据导入工作,同时gs_loader将\COPY结果记录到日志中。
  • 使用gs_loader前请确保gs_loader版本与gsql版本、数据库版本保持一致。

日志等级配置

设置日志级别,可以供开发者查看。设置后会在控制台打印工具运行的相应信息。

export gs_loader_log_level=debug
export gs_loader_log_level=info
export gs_loader_log_level=warning
export gs_loader_log_level=error

使用权限

使用场景分为三权分立场景下及非三权分立场景下的使用。使用者可以选择将guc参数enableSeparationOfDuty设置为on/off控制三权分立功能的开闭。

  • 不开启三权分立时,即enableSeparationOfDuty=off:

    使用者可以是数据库普通用户或管理员用户。当使用者为普通用户的时候,需要管理员用户对普通用户赋权。管理员账户可以直接使用。

    创建用户。

    CREATE USER load_user WITH PASSWORD '************';

    创建相关的表并授权。

    GRANT ALL ON FUNCTION copy_error_log_create() TO load_user;
    GRANT ALL ON SCHEMA public TO load_user;
    SELECT copy_error_log_create();
    SELECT copy_summary_create();
    GRANT ALL PRIVILEGES ON  public.pgxc_copy_error_log To load_user;
    GRANT ALL PRIVILEGES ON  public.gs_copy_summary To load_user;
  • 开启三权分立时,即enableSeparationOfDuty=on:

    使用者可以是数据库普通用户或管理员用户。使用前需要到各自的schema下创建pgxc_copy_error_log表以及gs_copy_summary这两张表并添加索引,不需要再进行授权。

    创建用户。

    CREATE USER load_user WITH PASSWORD '********';

    创建相关的表并添加索引。

    CREATE TABLE load_user.pgxc_copy_error_log (relname varchar, begintime timestamptz, filename varchar, lineno int8, rawrecord text, detail text);
    CREATE INDEX copy_error_log_relname_idx ON load_user.pgxc_copy_error_log(relname);
    CREATE TABLE load_user.gs_copy_summary(relname varchar, begintime timestamptz, endtime timestamptz, id bigint, pid bigint, readrows bigint, skiprows bigint, loadrows bigint, errorrows bigint, whenrows bigint, allnullrows bigint, detail text);
    CREATE INDEX gs_copy_summary_idx ON load_user.gs_copy_summary(id);

使用环境

由用户自己将工具路径添加到PATH中。gs_loader支持SSL加密通信,使用方式同gsql方式,具体操作请参考《管理员指南》中“安全管理”章节。

新增系统表

新增gs_copy_summary表,记录COPY执行结果汇总,包括成功行数,出错行数,忽略行数,空行数。

新增函数:copy_summary_create用于创建gs_copy_summary表。

gs_copy_summary表格式如下:

relname     | public.sqlldr_tbl
begintime   | 2021-09-03 16:00:11.7129-04
endtime     | 2021-09-03 16:00:15.259908-04
id          | 21870
pid         | 47582725060352
readrows    | 100000
skiprows    | 0
loadrows    | 111
errorrows   | 0
whenrows    | 99889
allnullrows | 0
detail      | 111 Rows successfully loaded.
            | 0 Rows not loaded due to data errors.
            | 99889 Rows not loaded because all WHEN clauses were failed.
            | 0 Rows not loaded because all fields were null.
            | 

使用指导

  1. 创建用户、相关表并添加索引。

    • (不开启三权分立)仅对于普通用户。

      创建用户。

      CREATE USER load_user WITH PASSWORD '************';

      创建相关的表并授权。

      GRANT ALL ON FUNCTION copy_error_log_create() TO load_user;
      GRANT ALL ON SCHEMA public TO load_user;
      SELECT copy_error_log_create();
      SELECT copy_summary_create();
      GRANT ALL PRIVILEGES ON  public.pgxc_copy_error_log To load_user;
      GRANT ALL PRIVILEGES ON  public.gs_copy_summary To load_user;
    • (开启三权分立)对于普通用户和管理员用户。

      创建用户。

      CREATE USER load_user WITH PASSWORD '********';

      创建相关的表并添加索引。

      CREATE TABLE load_user.pgxc_copy_error_log (relname varchar, begintime timestamptz, filename varchar, lineno int8, rawrecord text, detail text);
      CREATE INDEX copy_error_log_relname_idx ON load_user.pgxc_copy_error_log(relname);
      CREATE TABLE load_user.gs_copy_summary(relname varchar, begintime timestamptz, endtime timestamptz, id bigint, pid bigint, readrows bigint, skiprows bigint, loadrows bigint, errorrows bigint, whenrows bigint, allnullrows bigint, detail text);
      CREATE INDEX gs_copy_summary_idx ON load_user.gs_copy_summary(id);

  2. 创建表和控制文件,准备数据文件。

    创建表loader_tbl。

    1
    2
    3
    4
    5
    6
    7
    CREATE TABLE  loader_tbl
    (
        ID   NUMBER,
        NAME VARCHAR2(20),
        CON  VARCHAR2(20),
        DT   DATE
    );
    

    创建控制文件loader.ctl。

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    LOAD DATA
    truncate into table loader_tbl
    WHEN (2:2) = ',' 
    fields terminated by ','
    trailing nullcols
    (
        id integer external,
        name char(32),
        con ":id || '-' || :name",
        dt date
    )
    

    创建数据文件data.csv。

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    1,OK,,2007-07-8
    2,OK,,2008-07-8
    3,OK,,2009-07-8
    4,OK,,2007-07-8
    43,DISCARD,,2007-07-8
    ,,,
    32,DISCARD,,2007-07-8
    a,ERROR int,,2007-07-8
    8,ERROR date,,2007-37-8
    ,,,,
     ,
    8,ERROR fields,,2007-37-8
    ,,,
    5,OK,,2021-07-30
    

  3. 进行导入。

    执行导入前,先确认gs_loader工具有可执行权限。确保当前路径有文件写入权限(gs_loader在处理过程中会生成一些临时文件,导入完成后自动删除)。

    1
    gs_loader control=loader.ctl data=data.csv db=testdb bad=loader.bad errors=5 port=8000 passwd=************ user=load_user
    

    执行结果:

    1
    2
    3
    4
    5
    6
    gs_loader: version 0.1
     
     10 Rows successfully loaded. 
     
    log file is: 
     loader.log
    

参数说明

表1 gs_loader参数说明

参数

参数说明

参数类型 : 取值范围

help

查看帮助信息。

-

user

数据库连接用户(与-U等价)。

字符串

-U

数据库连接用户(与user等价)。

字符串

passwd

用户密码(与-W等价)。

字符串

-W

用户密码(与passwd等价)。

字符串

db

数据库名称(必选,与-d等价)。

字符串

-d

数据库名称(必选与db等价)。

字符串

host

指定正在运行服务器的主机名或者UNIX域套接字的路径(与-h等价)。

参考gsql --host参数

-h

指定正在运行服务器的主机名或者UNIX域套接字的路径(与host等价)。

参考gsql --host参数

port

数据库服务器端口(与-p等价)。

参考gsql --port参考

-p

数据库服务器端口(与port等价)。

参考gsql --port参考

create

是否创建pgxc_copy_error_log和gs_copy_summary表。

[true, false],默认true

clean

是否清除本次错误记录。

[true, false],默认false

data

数据文件,可以指定多个,或者通配符多字符通配(*)以及单字符通配(?)(必选)。

字符串

control

控制文件名称(必选)。

字符串

log

日志文件名称。

字符串

bad

出错行记录文件名称,也可以指定目录,根据数据文件名生成。

字符串

discard

WHEN匹配失败行记录文件名称,也可以指定目录,根据数据文件名生成。

字符串

errors

允许数据文件中出现多少出错行。

整数,默认0

skip

允许跳过数据文件的前多少行。

整数,默认0

bindsize

仅做语法兼容不实现功能。

-

rows

仅做语法兼容不实现功能。

-

  • 参数均为小写,不支持大写,同时兼容gsql登录方式:-p端口号,-h主机,-d数据库,-U用户名,-W密码方式。
  • gs_loader使用bad文件来记录出错数据,该数据来自错误表的rawrecord字段,由于错误表对于以某种编码无法读起的错误不记录rawrecord,因此bad文件中遇到此情况时记录空行。

控制文件

  • 语法说明:
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    LOAD [ DATA ]
    [CHARACTERSET char_set_name]
    [INFILE [directory_path] [filename ] ]
    [BADFILE [directory_path] [filename ] ]
    [{ INSERT | APPEND | REPLACE | TRUNCATE }] 
    INTO TABLE table_name
    [{ INSERT | APPEND | REPLACE | TRUNCATE }] 
    [FIELDS CSV]
    [TERMINATED [BY] { 'string' }]
    [OPTIONALLY ENCLOSED BY { 'string' }]
    [TRAILING NULLCOLS]
    [ WHEN { (start:end) | column_name } {= | !=} string ]
    [(
    col_name [ [ POSITION ({ start:end }) ]  ["sql_string"] ] | [ FILLER [column_type [external] ] ] | [ CONSTANT "string" ] | [ SEQUENCE ( { COUNT | MAX | integer } [, incr] ) ]|[NULLIF (COL=BLANKS)]
    [, ...]
    )]
    
  • 参数说明:
    • CHARACTERSET

      字符集。

      取值范围:字符串。

    • INFILE

      当前关键字无效,并在控制文件中需要单独占一行,运行时候会忽略该关键字。需要用户在gs_loader命令行参数中指定对应的数据文件。

    • BADFILE

      当前关键字无效,运行时候会忽略该关键字,如果gs_loader命令行参数没有指定badfile,则会根据对应控制文件名称生成对应的badfile文件。

    • INSERT | APPEND | REPLACE | TRUNCATE

      导入模式。

      INSERT:如果表中有数据,则报错。

      APPEND:直接插入数据。

      REPLACE:如果表中有数据,则全部删除,然后再插入。

      TRUNCATE:如果表中有数据,则全部删除,然后再插入。

      • 在写控制文件(.ctl)文件时,在INTO TABLE table_name语句前后都可以指定(导入模式,INSERT | APPEND | REPLACE | TRUNCATE),使用优先级为:在INTO TABLE table_name语句后面指定导入模式优先级高于在INTO TABLE table_name语句前面指定导入模式,在INTO TABLE table_name语句后面指定导入模式会覆盖在前面指定的导入模式。
      • 当开启多个gs_loader会话,并发地向同一张表中导入数据时,推荐以APPEND的方式进行导入,以INSERT|REPLACE|TRUNCATE的方式会出现导入报错或数据导入不全的问题。
    • table_name

      表的名称(可以有模式修饰)。

      取值范围:已存在的表名。

    • FIELDS csv

      标识使用copy的csv模式。在CSV模式下分隔符缺省值为逗号,引号字符的缺省值为双引号。

    • TERMINATED [BY] { 'string' }

      在文件中分隔各个字段的字符串,分隔符最大长度不超过10个字节。

      取值范围:不允许包含\.abcdefghijklmnopqrstuvwxyz0123456789中的任何一个字符。

      缺省值:在文本模式下,缺省是水平制表符,在CSV模式下是一个逗号。

    • OPTIONALLY ENCLOSED BY { 'string' }

      CSV格式文件下的引号字符。

      仅在使用FIELDS CSV明确说明的CSV模式下缺省值:双引号。

      其余模式下无缺省值。

      设置OPTIONALLY ENCLOSED BY { 'string' }时,数据左边可以不带引号字符;若有引号字符,则左右都必须为奇数个,但不必相等。

    • TRAILING NULLCOLS

      当数据加载时,若数据源文件中一行的多个字段缺失的处理方式。

    • WHEN { (start:end) | column_name } {= | !=}

      对行中的start到end之间的字符串,或者根据列名进行行过滤。

      取值范围:字符串。

    • POSITION ({ start:end })

      对列进行处理,根据start到end范围获取对应字符串。

    • "sql_string"

      对列进行处理,列表达式,根据表达式计算列的取值。

      取值范围:字符串。

    • FILLER

      对列进行处理,如果出现FILLER,则这个字段跳过。

    • CONSTANT

      对列进行处理,将插入的对应字段设置为常量。

      取值范围:字符串。

    • SEQUENCE ( { COUNT | MAX | integer } [, incr] )

      对列进行处理,生成对应的序列值。

      • COUNT:表示根据表中数据的行数开始计算。
      • MAX:表示根据表中这一列的最大值开始计算。
      • integer:表示从用户指定的值开始计算。
      • incr:表示每次递增多少。
    • NULLIF

      设置字段为空,当前只支持 COL POSITION() CHAR NULLIF (COL=BLANKS)语法。

    • OPTIONS ,INFILE,BADFILE不支持,仅在特定场景下不报语法错误。
    • gs_loader使用bad文件来记录出错数据,该数据来自错误表的rawrecord字段,由于错误表对于以某种编码无法读起的错误不记录rawrecord,因此bad文件中遇到此情况时记录空行。