华为云用户手册

  • 参数说明 复合类型 name 要创建的类型的名称(可以被模式限定)。 attribute_name 复合类型的一个属性(列)的名称。 data_type 要成为复合类型的一个列的现有数据类型的名称。可以使用%ROWTYPE间接引用表的类型,或者使用%TYPE间接引用表或复合类型中某一列的类型。 collation 要关联到复合类型的一列的现有排序规则的名称。排序规则可以使用“select * from pg_collation”命令从pg_collation系统表中查询,默认的排序规则为查询结果中以default开始的行。 基本类型 自定义基本类型时,参数可以以任意顺序出现,input_function和output_function为必选参数,其它为可选参数。 input_function 将数据从类型的外部文本形式转换为内部形式的函数名。 输入函数可以被声明为有一个cstring类型的参数,或者有三个类型分别为cstring、 oid、integer的参数。 cstring参数是以C字符串存在的输入文本。 oid参数是该类型自身的OID(对于数组类型则是其元素类型的OID)。 integer参数是目标列的typmod(如果知道,不知道则将传递 -1)。 输入函数必须返回一个该数据类型本身的值。通常,一个输入函数应该被声明为STRICT。 如果不是这样,在读到一个NULL输入值时,调用输入函数时第一个参数会是NULL。在这种情况下,该函数必须仍然返回NULL,除非调用函数发生了错误(这种情况主要是想支持域输入函数,域输入函数可能需要拒绝NULL输入)。 输入和输出函数能被声明为具有新类型的结果或参数是因为:必须在创建新类型之前创建这两个函数。而新类型应该首先被定义为一种shell type,它是一种占位符类型,除了名称和拥有者之外它没有其他属性。这可以通过不带额外参数的命令CREATE TYPE name做到。然后用C写的I/O函数可以被定义为引用这种shell type。最后,用带有完整定义的CREATE TYPE把该shell type替换为一个完全的、合法的类型定义,之后新类型就可以正常使用了。 输入和输出函数若为internel类型且指定为内部系统函数,则其输入函数和输出函数的参数类型需保持一致,且新类型的INTERNALLENGTH和PASSEDBYVALUE需要与输入函数和输出函数的参数类型保持一致。 output_function 将数据从类型的内部形式转换为外部文本形式的函数名。 输出函数必须被声明为有一个新数据类型的参数。输出函数必须返回类型cstring。对于NULL值不会调用输出函数。 receive_function 可选参数。将数据从类型的外部二进制形式转换成内部形式的函数名。 如果没有该函数,该类型不能参与到二进制输入中。二进制表达转换成内部形式代价更低,然而却更容易移植(例如,标准的整数数据类型使用网络字节序作为外部二进制表达,而内部表达是机器本地的字节序)。receive_function应该执行足够的检查以确保该值是有效的。 接收函数可以被声明为有一个internal类型的参数,或者有三个类型分别为internal、oid、integer的参数。 internal参数是一个指向StringInfo缓冲区的指针,其中保存着接收到的字节串。 oid和integer参数和文本输入函数的相同。 接收函数必须返回一个该数据类型本身的值。通常,一个接收函数应该被声明为STRICT。如果不是这样,在读到一个NULL输入值时调用接收函数时第一个参数会是NULL。在这种情况下,该函数必须仍然返回NULL,除非接收函数发生了错误(这种情况主要是想支持域接收函数,域接收函数可能需要拒绝NULL输入)。 send_function 可选参数。将数据从类型的内部形式转换为外部二进制形式的函数名。 如果没有该函数,该类型将不能参与到二进制输出中。发送函数必须被声明为有一个新数据类型的参数。发送函数必须返回类型bytea。对于NULL值不会调用发送函数。 type_modifier_input_function 可选参数。将类型的修饰符数组转换为内部形式的函数名。 type_modifier_output_function 可选参数。将类型的修饰符的内部形式转换为外部文本形式的函数名。 如果该类型支持修饰符(附加在类型声明上的可选约束,例如,char(5)或numeric(30,2)),则需要可选的type_modifier_input_function以及type_modifier_output_function。 GaussDB 允许用户定义的类型有一个或者多个简单常量或者标识符作为修饰符。不过,为了存储在系统目录中,该信息必须能被打包到一个非负整数值中。所声明的修饰符会被以cstring数组的形式传递给type_modifier_input_function。 type_modifier_input_function必须检查该值的合法性(如果值错误就抛出一个错误),如果值正确,要返回一个非负integer值,该值将被存储在“typmod”列中。如果类型没有 type_modifier_input_function则类型修饰符将被拒绝。type_modifier_output_function把内部的整数typmod值转换回正确的形式用于用户显示。type_modifier_output_function必须返回一个cstring值,该值就是追加到类型名称后的字符串。例如,numeric的函数可能会返回(30,2)。如果默认的显示格式就是只把存储的typmod整数值放在圆括号内,则允许省略type_modifier_output_function。 analyze_function 可选参数。为该数据类型执行统计分析的函数名的可选参数。 默认情况下,如果该类型有一个默认的B-tree操作符类,ANALYZE将尝试用类型的“equals”和“less-than”操作符来收集统计信息。这种行为对于非标量类型并不合适,因此可以通过指定一个自定义分析函数来覆盖这种行为。分析函数必须被声明为有一个类型为internal的参数,并且返回一个boolean结果。 internallength 可选参数。一个数字常量,用于指定新类型的内部表达的字节长度。默认为变长。 虽然只有I/O函数和其他为该类型创建的函数才知道新类型的内部表达的细节, 但是内部表达的一些属性必须被向GaussDB声明。其中最重要的是internallength。基本数据类型可以是定长的(这种情况下internallength是一个正整数)或者是变长的(把internallength设置为VARIABLE,在内部通过把typlen设置为-1表示)。所有变长类型的内部表达都必须以一个4字节整数开始,internallength定义了总长度。 PASSEDBYVALUE 可选参数。表示这种数据类型的值需要被传值而不是传引用。传值的类型必须是定长的,并且它们的内部表达不能超过Datum类型(某些机器上是4字节,其他机器上是8字节)的尺寸。 alignment 可选参数。该参数指定数据类型的存储对齐需求。如果被指定,必须是char、int2、int4或者double。默认是int4。 允许的值等同于以1、2、4或8字节边界对齐。要注意变长类型的alignment参数必须至少为4,因为它们需要包含一个int4作为它们的第一个组成部分。 storage 可选参数。该数据类型的存储策略。 如果被指定,必须是plain、external、extended或者main。 默认是plain。 plain指定该类型的数据将总是被存储在线内并且不会被压缩。(对定长类型只允许plain) extended 指定系统将首先尝试压缩一个长的数据值,并且将在数据仍然太长的情况下把值移出主表行。 external允许值被移出主表, 但是系统将不会尝试对它进行压缩。 main允许压缩,但是不鼓励把值移出主表(如果没有其他办法让行的大小变得合适,具有这种存储策略的数据项仍将被移出主表,但比起extended以及external项来,这种存储策略的数据项会被优先考虑保留在主表中)。 除plain之外所有的storage值都暗示该数据类型的函数能处理被TOAST过的值。指定的值仅仅是决定一种可TOAST数据类型的列的默认TOAST存储策略,用户可以使用ALTER TABLE SET STORAGE为列选取其他策略。 like_type 可选参数。与新类型具有相同表达的现有数据类型的名称。会从这个类型中复制internallength、 passedbyvalue、 alignment以及storage的值( 除非在这个CREATE TYPE命令的其他地方用显式说明覆盖)。 当新类型的低层实现是以一种现有的类型为参考时,用这种方式指定表达特别有用。 category 可选参数。这种类型的分类码(一个ASCII 字符)。 默认是“用户定义类型”的'U'。为了创建自定义分类, 也可以选择其他 ASCII字符。 preferred 可选参数。如果这种类型是其类型分类中的优先类型则为TRUE,否则为FALSE。默认为假。在一个现有类型分类中创建一种新的优先类型要非常谨慎, 因为这可能会导致很大的改变。 category和preferred参数可以被用来帮助控制在混淆的情况下应用哪一种隐式造型。每一种数据类型都属于一个用单个ASCII 字符命名的分类,并且每一种类型可以是其所属分类中的“首选”。当有助于解决重载函数或操作符时,解析器将优先造型到首选类型(但是只能从同类的其他类型造型)。对于没有隐式转换到或来自任意其他类型的类型,让这些设置保持默认即可。不过,对于有隐式转换的相关类型的组,把它们都标记为属于同一个类别并且选择一种或两种“最常用”的类型作为该类别的首选通常是很有用的。在把一种用户定义的类型增加到一个现有的内建类别(例如,数字或者字符串类型)中时,category参数特别有用。不过,也可以创建新的全部是用户定义类型的类别。对这样的类别,可选择除大写字母之外的任何ASCII 字符。 default 可选参数。数据类型的默认值。如果被省略,默认值是空。 如果用户希望该数据类型的列被默认为某种非空值,可以指定一个默认值。默认值可以用DEFAULT关键词指定(这样一个默认值可以被附加到一个特定列的显式DEFAULT子句覆盖)。 element 可选参数。被创建的类型是一个数组,element指定了数组元素的类型。例如,要定义一个4字节整数的数组(int4), 应指定ELEMENT = int4。 delimiter 可选参数。指定这种类型组成的数组中分隔值的定界符。 可以把delimiter设置为一个特定字符,默认的定界符是逗号(,)。注意定界符是与数组元素类型相关的,而不是数组类型本身相关。 collatable 可选参数。如果这个类型的操作可以使用排序规则信息,则为TRUE。默认为FALSE。 如果collatable为TRUE,这种类型的列定义和表达式可能通过使用COLLATE子句携带有排序规则信息。在该类型上操作的函数的实现负责真正利用这些信息,仅把类型标记为可排序的并不会让它们自动地去使用这类信息。 label 可选参数。与枚举类型的一个值相关的文本标签,其值为长度不超过63个字符的非空字符串。 在创建用户定义类型的时候, GaussDB会自动创建一个与之关联的数组类型,其名称由该元素类型的名称前缀一个下划线组成。
  • 操作步骤 创建表空间 执行如下命令创建用户jack。 1 gaussdb=# CREATE USER jack IDENTIFIED BY '********'; 当结果显示为如下信息,则表示创建成功。 1 CREATE ROLE 执行如下命令创建表空间。 1 gaussdb=# CREATE TABLESPACE fastspace RELATIVE LOCATION 'tablespace/tablespace_1'; 当结果显示为如下信息,则表示创建成功。 1 CREATE TABLESPACE 其中“fastspace”为新创建的表空间,“数据库节点数据目录/pg_location/tablespace/tablespace_1”是用户拥有读写权限的空目录。 数据库系统管理员执行如下命令将“fastspace”表空间的访问权限赋予数据用户jack。 1 gaussdb=# GRANT CREATE ON TABLESPACE fastspace TO jack; 当结果显示为如下信息,则表示赋予成功。 1 GRANT
  • 示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 gaussdb=# CREATE TABLE t1(a int); gaussdb=# INSERT INTO t1 VALUES(1),(10); --RETURN NEXT gaussdb=# CREATE OR REPLACE FUNCTION fun_for_return_next() RETURNS SETOF t1 AS $$ DECLARE r t1%ROWTYPE; BEGIN FOR r IN select * from t1 LOOP RETURN NEXT r; END LOOP; RETURN; END; $$ LANGUAGE plpgsql; gaussdb=# call fun_for_return_next(); a --- 1 10 (2 rows) -- RETURN QUERY gaussdb=# CREATE OR REPLACE FUNCTION fun_for_return_query() RETURNS SETOF t1 AS $$ DECLARE r t1%ROWTYPE; BEGIN RETURN QUERY select * from t1; END; $$ language plpgsql; gaussdb=# call fun_for_return_query(); a --- 1 10 (2 rows)
  • 示例 1 2 3 4 --删除列加密密钥。 gaussdb=# DROP COLUMN ENCRYPTION KEY ImgCEK CASCADE; ERROR: cannot drop column setting: imgcek cascadely because encrypted column depend on it. HINT: we have to drop encrypted column: name, ... before drop column setting: imgcek cascadely.
  • 下标生成函数 generate_subscripts(array anyarray, dim int) 描述:生成一系列包括给定数组的下标。 返回值类型:setof int generate_subscripts(array anyarray, dim int, reverse boolean) 描述:生成一系列包括给定数组的下标。当reverse为真时,该系列则以相反的顺序返回。 返回值类型:setof int
  • DBE_SQL_UTIL Schema DBE_SQL_UTIL模式存储了用于管理SQL PATCH的工具,包括创建、删除、开启、禁用SQL PATCH等系统函数。普通用户只有usage权限,没有create、alter、drop、comment等权限。 DBE_SQL_UTIL Schema使用请参考使用SQL PATCH进行调优。 DBE_SQL_UTIL.create_hint_sql_patch DBE_SQL_UTIL.create_abort_sql_patch DBE_SQL_UTIL.drop_sql_patch DBE_SQL_UTIL.enable_sql_patch DBE_SQL_UTIL.disable_sql_patch DBE_SQL_UTIL.show_sql_patch DBE_SQL_UTIL.create_hint_sql_patch DBE_SQL_UTIL.create_abort_sql_patch 父主题: Schema
  • 处理查询 GaussDB提供了函数和操作符用来操作tsquery类型的查询。 tsquery && tsquery 返回两个给定查询tsquery的与结果。 tsquery || tsquery 返回两个给定查询tsquery的或结果。 !! tsquery 返回给定查询tsquery的非结果。 numnode(query tsquery) returns integer 返回tsquery中的节点数目(词素加操作符),这个函数在检查查询是否有效(返回值大于0),或者只包含停用词(返回值等于0)时,是有用的。例如: 1 2 3 4 5 6 7 8 9 10 11 gaussdb=# SELECT numnode(plainto_tsquery('the any')); NOTICE: text-search query contains only stop words or doesn't contain lexemes, ignored CONTEXT: referenced column: numnode numnode --------- 0 gaussdb=# SELECT numnode('foo & bar'::tsquery); numnode --------- 3 querytree(query tsquery) returns text 返回可用于索引搜索的tsquery部分,该函数对于检测非索引查询是有用的(例如只包含停用词或否定项)。例如: 1 2 3 4 5 gaussdb=# SELECT querytree(to_tsquery('!defined')); querytree ----------- T (1 row) 父主题: 附加功能
  • PG_SYNONYM PG_SYNONYM系统表存储同义词对象名与其他数据库对象名间的映射信息。 表1 PG_SYNONYM字段 名称 类型 描述 oid oid 行标识符(隐含字段,必须明确选择)。 synname name 同义词名称。 synnamespace oid 包含该同义词的名字空间的OID。 synowner oid 同义词的所有者,通常是创建它的用户OID。 synobjschema name 关联对象指定的模式名。 synobjname name 关联对象名。 syndblinkname name 关联DATABASE LINK对象名。 父主题: 系统表
  • 参数说明 name 要创建的聚合函数名(可以有模式修饰) 。 input_data_type 该聚合函数要处理的输入数据类型。要创建一个零参数聚合函数,可以使用*代替输入数据类型列表。 (count(*)就是这种聚合函数的一个实例。 ) base_type 在以前的CREATE AGGREGATE语法中,输入数据类型是通过basetype参数指定的,而不是写在聚合的名称之后。 需要注意的是这种以前语法仅允许一个输入参数。 要创建一个零参数聚合函数,可以将basetype指定为"ANY"(而不是*)。 sfunc 将在每一个输入行上调用的状态转换函数的名称。 对于有N个参数的聚合函数,sfunc必须有 +1 个参数,其中的第一个参数类型为state_data_type,其余的匹配已声明的输入数据类型。 函数必须返回一个state_data_type类型的值。 这个函数接受当前状态值和当前输入数据,并返回下个状态值。 state_data_type 聚合的状态值的数据类型。 ffunc 在转换完所有输入行后调用的最终处理函数,它计算聚合的结果。 此函数必须接受一个类型为state_data_type的参数。 聚合的输出数据 类型被定义为此函数的返回类型。 如果没有声明ffunc则使用聚合结果的状态值作为聚合的结果,且输出类型为state_data_type。 initial_condition 状态值的初始设置(值)。 它必须是一个state_data_type类型可以接受的文本常量值。 如果没有声明,状态值初始为 NULL 。 sort_operator 用于MIN或MAX类型聚合的排序操作符。 这个只是一个操作符名 (可以有模式修饰)。这个操作符假设接受和聚合一样的输入数据类型。 collection_func 目前该参数在集中式下不生效。
  • 优化分析 分析发现上述计划的性能瓶颈点为lfbank.f_ev_dp_kdpl_zhminx的scan。进一步分析该表的Scan条件如下: 尝试把lfbank.f_ev_dp_kdpl_zhminx表修改为列存表,然后在yezdminc列上建PCK(局部聚簇),并设置PARTIAL_CLUSTER_ROWS=100000000(此用例lfbank.f_ev_dp_kdpl_zhminx表行数为116702554,PARTIAL_CLUSTER_ROWS默认值4200000)。执行计划优化为: 此方法实际是靠牺牲数据导入时的性能来提升业务查询性能。 此方法导致局部排序的元组数增加,需要增大psort_work_mem来提高排序效率。
  • 示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 --建立外表,用来以TEXT格式导入GDS服务器192.168.0.90和192.168.0.91上的数据,导入过程错误信息将记录到err_HR_staffS中。 gaussdb=# CREATE FOREIGN TABLE foreign_HR_staffS ( staff_ID NUMBER(6) , FIRST_NAME VARCHAR2(20), LAST_NAME VARCHAR2(25), EMAIL VARCHAR2(25), PHONE_NUMBER VARCHAR2(20), HIRE_DATE DATE, employment_ID VARCHAR2(10), SALARY NUMBER(8,2), COMMISSION_PCT NUMBER(2,2), MANAGER_ID NUMBER(6), section_ID NUMBER(4) ) SERVER gsmpp_server OPTIONS (location 'gsfs://192.168.0.90:5000/* | gsfs://192.168.0.91:5000/*', format 'TEXT', delimiter E'\x20', null '') WITH err_HR_staffS; 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 --建立外表,用来以TEXT格式导入GDS服务器192.168.0.90和192.168.0.91上的数据,导入过程错误信息将记录到err_HR_staffS中。本次数据导入允许出现的数据格式错误个数为2。 CREATE FOREIGN TABLE foreign_HR_staffS_ft3 ( staff_ID NUMBER(6) , FIRST_NAME VARCHAR2(20), LAST_NAME VARCHAR2(25), EMAIL VARCHAR2(25), PHONE_NUMBER VARCHAR2(20), HIRE_DATE DATE, employment_ID VARCHAR2(10), SALARY NUMBER(8,2), COMMISSION_PCT NUMBER(2,2), MANAGER_ID NUMBER(6), section_ID NUMBER(4) ) SERVER gsmpp_server OPTIONS (location 'gsfs://192.168.0.90:5000/* | gsfs://192.168.0.91:5000/*', format 'TEXT', delimiter E'\x20', null '',reject_limit '2') WITH err_HR_staffS_ft3; 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 --建立外表,用来以 CS V格式导入input_data目录下存放在各个节点名文件下的所有文件。 gaussdb=# CREATE FOREIGN TABLE foreign_HR_staffS_ft1 ( staff_ID NUMBER(6) , FIRST_NAME VARCHAR2(20), LAST_NAME VARCHAR2(25), EMAIL VARCHAR2(25), PHONE_NUMBER VARCHAR2(20), HIRE_DATE DATE, employment_ID VARCHAR2(10), SALARY NUMBER(8,2), COMMISSION_PCT NUMBER(2,2), MANAGER_ID NUMBER(6), section_ID NUMBER(4) ) SERVER gsmpp_server OPTIONS (location 'file:///input_data/*', format 'csv', mode 'private', delimiter ',') WITH err_HR_staffS_ft1; 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 --建立外表,用来以CSV格式导出数据到output_data目录下。 gaussdb=# CREATE FOREIGN TABLE foreign_HR_staffS_ft2 ( staff_ID NUMBER(6) , FIRST_NAME VARCHAR2(20), LAST_NAME VARCHAR2(25), EMAIL VARCHAR2(25), PHONE_NUMBER VARCHAR2(20), HIRE_DATE DATE, employment_ID VARCHAR2(10), SALARY NUMBER(8,2), COMMISSION_PCT NUMBER(2,2), MANAGER_ID NUMBER(6), section_ID NUMBER(4) ) SERVER gsmpp_server OPTIONS (location 'file:///output_data/', format 'csv', delimiter '|', header 'on') WRITE ONLY; 1 2 3 4 5 --删除外表。 gaussdb=# DROP FOREIGN TABLE foreign_HR_staffS; gaussdb=# DROP FOREIGN TABLE foreign_HR_staffS_ft1; gaussdb=# DROP FOREIGN TABLE foreign_HR_staffS_ft2; gaussdb=# DROP FOREIGN TABLE foreign_HR_staffS_ft3;
  • 参数概览 创建外表语法提供了多个参数,常用参数分类如下。 必需参数 table_name column_name type_name POSITION(offset,length) LIKE source_table SERVER server_name OPTIONS可选参数 可选参数 外表的数据源位置参数location 数据格式参数 format header(仅支持CSV,FIXED格式) fileheader(仅支持CSV,FIXED格式) out_filename_prefix delimiter quote(仅支持CSV格式) escape(仅支持CSV格式) null noescaping(仅支持TEXT格式) encoding eol 容错性参数 fill_missing_fields ignore_extra_data reject_limit compatible_illegal_chars WITH error_table_name LOG INTO error_table_nam... REMOTE LOG 'name' PER NODE REJECT LIMIT 'v...
  • 语法格式 1 2 3 4 5 6 7 8 9 CREATE FOREIGN TABLE [ IF NOT EXISTS ] table_name ( [ { column_name type_name POSITION ( offset, length ) | LIKE source_table } [, ...] ] ) SERVER server_name OPTIONS ( { option_name 'value' } [, ...] ) [ WRITE ONLY | READ ONLY ] [ WITH error_table_name | LOG INTO error_table_name] [REMOTE LOG 'name'] [PER NODE REJECT LIMIT 'value'] [ TO { GROUP groupname | NODE ( nodename [, ... ] ) } ];
  • 示例 1 2 3 4 5 6 7 8 9 10 11 12 --创建资源池pool1。 gaussdb=# CREATE RESOURCE POOL pool1; --创建负载组group1。 gaussdb=# CREATE WORKLOAD GROUP group1; -- 更新一个负载组group1的并发数量为10。其关联的资源池为pool1。 gaussdb=# ALTER WORKLOAD GROUP group1 USING RESOURCE POOL pool1 WITH (ACT_STATEMENTS=10); --删除负载组group1和资源池pool1。 gaussdb=# DROP WORKLOAD GROUP group1; gaussdb=# DROP RESOURCE POOL pool1;
  • 示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 -- 创建一个资源池,其控制组指定为"DefaultClass"组下属的"High" Timeshare Workload控制组。 gaussdb=# CREATE RESOURCE POOL pool1 WITH (CONTROL_GROUP="High"); -- 创建一个负载组,关联已创建的资源池。 gaussdb=# CREATE WORKLOAD GROUP group1 USING RESOURCE POOL pool1; -- 创建一个应用映射组,关联已创建的负载组。 gaussdb=# CREATE APP WORKLOAD GROUP MAPPING app_wg_map1 WITH (WORKLOAD_GPNAME=group1); --创建一个默认应用映射组,关联默认的负载组。 gaussdb=# CREATE APP WORKLOAD GROUP MAPPING app_wg_map2; --删除应用映射组。 gaussdb=# DROP APP WORKLOAD GROUP MAPPING app_wg_map1; gaussdb=# DROP APP WORKLOAD GROUP MAPPING app_wg_map2; --删除负载组。 gaussdb=# DROP WORKLOAD GROUP group1; --删除资源池。 gaussdb=# DROP RESOURCE POOL pool1;
  • 示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 --创建模式ds。 gaussdb=# CREATE SCHEMA ds; --将当前模式ds更名为ds_new。 gaussdb=# ALTER SCHEMA ds RENAME TO ds_new; --创建用户jack。 gaussdb=# CREATE USER jack PASSWORD '********'; --将DS_NEW的所有者修改为jack。 gaussdb=# ALTER SCHEMA ds_new OWNER TO jack; --修改ds_new的防篡改属性。 gaussdb=# ALTER SCHEMA ds_new WITH BLOCKCHAIN; --删除用户jack和模式ds_new。 gaussdb=# DROP SCHEMA ds_new; gaussdb=# DROP USER jack;
  • 参数说明 pool_name 资源池名称。 资源池名称为已创建的资源池。 取值范围:字符串,要符合标识符命名规范。 group_name 控制组名称。 设置控制组名称时,语法可以使用双引号,也可以使用单引号。 group_name对大小写敏感。 不指定group_name时,默认指定的字符串为 "Medium",代表指定DefaultClass控制组的"Medium" Timeshare控制组。 若数据库管理员指定自定义Class组下的Workload控制组,如control_group的字符串为:"class1:workload1";代表此资源池指定到class1控制组下的workload1控制组。也可同时指定Workload控制组的层次,如control_group的字符串为:"class1:workload1:1"。 若数据库用户指定Timeshare控制组代表的字符串,即"Rush"、"High"、"Medium"或"Low"其中一种,如control_group的字符串为"High";代表资源池指定到DefaultClass控制组下的"High" Timeshare控制组。 多租户场景下,组资源池关联的控制组为class级别,业务资源池关联Workload控制组。且不允许在各种资源池间相互切换。 取值范围:已创建的控制组。 stmt 资源池语句执行的最大并发数量。 取值范围:数值型,-1~2147483647,-1表示不限制并发数 dop 资源池最大并发度,语句执行时能够创建的最多线程数量。 取值范围:数值型,1~2147483647‬。 memory_size 资源池最大使用内存。 取值范围:字符串,内容范围1KB~2047GB,单位大小写敏感 mem_percent 资源池可用内存占全部内存或者组用户内存使用的比例。 在多租户场景下,组用户和业务用户的mem_percent范围为1-100的整数,默认为20。 在普通场景下,普通用户的mem_percent范围为0-100的整数,默认值为0。 mem_percent和memory_limit同时指定时,只有mem_percent起作用。 io_limits 资源池每秒可触发IO次数上限。 对于行存,以万次为单位计数,而列存则以正常次数计数。 取值范围:数值型,0-2147483647 io_priority IO利用率高达90%时,重消耗IO作业进行IO资源管控时关联的优先级等级。 包括三档可选:Low、Medium和High。不控制时可设置为None,默认为None。 取值范围:枚举型,可选项为:None,Low、Medium和High。 io_limits和io_priority的设置都仅对复杂作业有效。包括批量导入(INSERT INTO SELECT, COPY FROM, CREATE TABLE AS等),单DN数据量大约超过500MB的复杂查询和VACUUM FULL等操作。
  • 语法格式 1 2 ALTER RESOURCE POOL pool_name WITH ({MEM_PERCENT= pct | CONTROL_GROUP="group_name" | ACTIVE_STATEMENTS=stmt | MAX_DOP = dop | MEMORY_LIMIT='memory_size' | io_limits=io_limits | io_priority='io_priority'}[, ... ]);
  • 编写代码 C语言函数的编写需要遵守基本的规则: 函数声明语法,Datum funcname(PG_FUNCTION_ARGS)。 申明函数是版本1格式,调用宏PG_FUNCTION_INFO_V1(funcname)。不使用宏则默认为版本0格式。 C文件中声明PG_MODULE_MAGIC,标记数据库的版本信息,防止动态库被加载到一个不兼容的服务器。 在分配内存时,使用函数palloc和pfree,而不是使用对应的C库函数malloc和free。在每个事务结束是会自动释放通过palloc申请的内存,以免内存泄露。 C文件中定义的符号名不能相互冲突或者与服务器中可执行程序中定义的符号冲突。如果有关于此的编译错误消息,你必须重命名你的函数或者变量。 开发者应充分了解要调用的内核函数接口功能及入参范围,在调用前应检查参数合法性,避免出现空指针等可能导致程序crash的问题。 自定义函数上线前应经过充分测试,避免引入问题影响数据库正常业务。
  • 示例 示例1:函数功能,返回两个时间中的较大的,文件名maxtimestamp.cpp,文件内容如下。 其中,PG_GETARG_TIMESTAMP(0)、PG_GETARG_TIMESTAMP(1)分别获取timestamp类型的第一个参数和第二个参数。PG_ARGISNULL(0)、PG_ARGISNULL(1)返回参数1、参数2是否为NULL。PG_RETURN_TIMESTAMP返回timestamp结果。
  • 支持的数据类型以及接口 数据库支持数字,字符串,时间等多种类型。目前C函数支持的类型,以及各种类型的C类型和SQL类型的对应关系,类型的参数获取以及返回结果的接口,见下表: 表1 C类型和SQL类型的对应关系 SQL类型 C类型 获取参数 返回结果 varchar VarChar* PG_GETARG_DATUM PG_RETURN_VARCHAR_P text text* PG_GETARG_DATUM PG_RETURN_TEXT_P char BpChar* PG_GETARG_DATUM PG_RETURN_BPCHAR_P date DateADT PG_GETARG_DATUM PG_RETURN_DATEADT timestamp Timestamp PG_GETARG_TIMESTAMP PG_RETURN_TIMESTAMP smallint int16 PG_GETARG_INT16 PG_RETURN_INT16 integer int32 PG_GETARG_INT32 PG_RETURN_INT32 bigint int64 PG_GETARG_INT64 PG_RETURN_INT64 常用函数及说明见下表: 表2 常用函数及说明 函数名 功能 TextDatumGetCString 传入text/varchar/bpchar的Datum类型,返回一个char*字符串 cstring_to_text 转换char*字符串到text/varchar类型 date_pl_interval date类型加一个时间间隔 timestamp_pl_interval timestamp类型加一个时间间隔 int4_numeric integer数据转换成numeric类型 palloc 内存申请 pfree 内存释放 PointerGetDatum 指针类型强制转换成Datum类型 DirectFunctionCall1 调用1个参数的函数 DirectFunctionCall2 调用2个参数的函数 DirectFunctionCall3 调用3个参数的函数 PG_ARGISNULL(N) 判断函数的第n个参数是否为NULL
  • 创建C函数 以ISNUMBER为例: 1 2 3 4 create or replace function isnumber(text) returns integer as '...../isNumber.so', 'ISNUMBER' language c strict fenced IMMUTABLE SHIIPABLE; ...../isNumber.so 指定了库文件的路径。当enable_default_cfunc_libpath打开时,只需要指定文件名即可,数据库会自动在默认目录($libdir/proc_srclib)下查找该文件。当enable_default_cfunc_libpath关闭时,这里必须指定库文件的绝对路径。enable_default_cfunc_libpath参数默认打开。 属性strict,表示只要其中任意参数为NULL值,该函数就会返回空值,当有NULL参数时该函数不会被执行,而是自动返回一个空值结果。也就是说,如果函数创建时没有指定strict属性,则函数的C语言实现一定要对参数是否为NULL特殊处理,例如:maxdate的实现。否则,对NULL的不正确的使用可能引起进程的crash。 属性fenced,如果指定函数为fenced模式,则函数会在worker进程中被调用,防止C代码实现错误导致服务器crash,不建议使用not fenced模式。 属性IMMUTABLE,表示函数的结果只倚赖于它的输入参数。 属性SHIPPABLE,表示这个函数可以下推到DN执行。对于IMMUTABLE类型的函数,如果函数的返回值类型不是record,则可以下推到DN上执行。 对于STABLE/VOLATILE类型的函数,仅当函数的属性是SHIPPABLE的时候,函数可以下推到DN执行。 函数属性在CREATE FUNCTION章节会有详细介绍。
  • 编译生成动态库 在使用用户定义的C代码之前,必须编译链接生成一个能被服务器动态载入的文件。确切的说,需要生成一个共享库文件。 首先源文件被编译成一个目标文件,然后目标文件被连接起来。目标文件需要被创建成position-independent code (PIC),这意味着当它们被载入时,可以被放置在内存中的任意位置。 下面例子中,我们以文件isNumber.c为例,并且创建一个共享库isNumber.so。 Linux创建PIC的编译器标志是-fpic。在不同平台上的,需要参考GCC手册。创建一个共享库的编译器标志是-shared。一个完整的例子: gcc -fpic -c isNumber.cpp -I include/postgresql/server/ gcc -shared -o isNumber.so isNumber.o 上述命令也可以连在一起: gcc -shared -fpic -o isNumber.so isNumber.cpp -I include/postgresql/server/ 其中include/postgresql/server/ 为服务器对外发布的头文件路径,在安装目录下面。 gcc版本要求在7.3.0或者7.3.0之上。 为保证C函数兼容性,若涉及数据库升级,用户需要基于升级后的头文件重新编译C函数共享库。 在服务端加载过动态库后,不可在环境上手动修改该动态库,否则可能出现段错误或其他未知问题。
  • Plan Hint实际调优案例 本节以TPC-DS标准测试的Q24的部分语句为例,在1000X,24DN环境上,说明使用plan hint进行实际调优的过程。示例如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 select avg(netpaid) from (select c_last_name ,c_first_name ,s_store_name ,ca_state ,s_state ,i_color ,i_current_price ,i_manager_id ,i_units ,i_size ,sum(ss_sales_price) netpaid from store_sales ,store_returns ,store ,item ,customer ,customer_address where ss_ticket_number = sr_ticket_number and ss_item_sk = sr_item_sk and ss_customer_sk = c_customer_sk and ss_item_sk = i_item_sk and ss_store_sk = s_store_sk and c_birth_country = upper(ca_country) and s_zip = ca_zip and s_market_id=7 group by c_last_name ,c_first_name ,s_store_name ,ca_state ,s_state ,i_color ,i_current_price ,i_manager_id ,i_units ,i_size); 该语句的初始计划如下,运行时间110s: 该计划中,第10层算子使用broadcast性能较差,由于第11层算子估算行数为2140,比实际行数严重低估。错误行数估算主要来源于第13层算子的行数低估,根因是第13层hashjoin中,使用store_sales的(ss_ticket_number, ss_item_sk)列和store_returns的(sr_ticket_number, sr_item_sk)列进行关联,由于缺少多列相关性的估算导致行数严重低估。 2. 使用如下的rows hint进行调优后,计划如下,运行时间318s: 1 2 select avg(netpaid) from (select /*+rows(store_sales store_returns * 11270)*/ c_last_name ... 时间反而劣化了,原因是第8层hashjoin过慢引起第9层redistribute时间过慢导致,其中第9层redistribute并没有数据倾斜,hashjoin慢的原因是由于第18层redistribute后数据倾斜导致。 3. 经过实际数据查证,customer_address的两个join列的不同值数目较少,使用其进行join容易出现数据倾斜,故把customer_address放到最后进行join。使用如下的hint进行调优后,计划如下,运行时间116s: 1 2 3 4 select avg(netpaid) from (select /*+rows(store_sales store_returns *11270) leading((store_sales store_returns store item customer) customer_address)*/ c_last_name ... 发现时间基本花在了第6层redistribute算子上,需要进一步优化。 4. 由于最后一层redistribute包含倾斜,所以时间较长。为了避免倾斜,需要将item表放在最后join,由于item表的join并不能使行数减少。修改hint如下并执行,计划如下,运行时间120s: 1 2 3 4 select avg(netpaid) from (select /*+rows(store_sales store_returns *11270) leading((customer_address (store_sales store_returns store customer) item)) c_last_name ... 该计划中的redistribute问题并没有解决,因为第22层item表做了broadcast,导致与customer_address表join后的倾斜并没有被消除掉。 5. 增加如下禁止item表做broadcast的hint,使与customer_address join的表做redistribute(也可以进行join表redistribute的hint),计划如下,运行时间105s: 1 2 3 4 5 select avg(netpaid) from (select /*+rows(store_sales store_returns *11270) leading((customer_address (store_sales store_returns store customer) item)) no broadcast(item)*/ c_last_name ... 6. 发现最后一层使用单层Agg,但行数缩减较多。使用相同的hint,同时结合参数best_agg_plan=3进行双层Agg调优,最终计划如下图所示,运行时间94s,完成调优。 如果有统计信息变更引起的查询劣化,可以考虑用plan hint来调整到之前的查询计划。这里以TPCH-Q17为例,在收集default_statistics_target设置为–2的统计信息之后,计划相比于默认统计信息发生劣化。 1. 默认统计信息(default_statistics_target设置为100)的计划如下: 2. 统计信息变更(default_statistics_target设置为–2)的计划如下: 3. 经过对比,劣化的原因主要为lineitem和part表join时stream类型由BroadCast变更为Redistribute导致。可以对语句进行stream方式的hint来调整到之前的计划,例如: 父主题: 使用Plan Hint进行调优
  • 示例 1 2 3 4 5 6 7 8 9 10 11 12 13 --创建一个角色role1。 gaussdb=# CREATE ROLE role1 IDENTIFIED BY '********'; -- 为用户role1创建一个同名schema,子命令创建的表films和winners的拥有者为role1。 gaussdb=# CREATE SCHEMA AUTHORIZATION role1 CREATE TABLE films (title text, release date, awards text[]) CREATE VIEW winners AS SELECT title, release FROM films WHERE awards IS NOT NULL; --删除schema。 gaussdb=# DROP SCHEMA role1 CASCADE; --删除用户。 gaussdb=# DROP USER role1 CASCADE;
  • 简化输入 简化输入到CSV日志文件,可以通过如下操作: 设置log_filename和log_rotation_age,为日志文件提供一个一致的、可预测的命名方案。通过日志文件名,预测一个独立的日志文件完成并进入准备导入状态的时间。 将log_rotation_size设为0来终止基于尺寸的日志回滚,因为基于尺寸的日志回滚让预测日志文件名变得非常的困难。 将log_truncate_on_rotation设为on以便区分在同一日志文件中旧的日志数据和新的日志数据。
  • csvlog定义 以“逗号分隔值” 即CSV(Comma Separated Value)的形式发出日志。 以下是简单的用来存储CSV形式日志输出的表定义: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 CREATE TABLE postgres_log ( log_time timestamp(3) with time zone, node_name text, user_name text, database_name text, process_id bigint, connection_from text, "session_id" text, session_line_num bigint, command_tag text, session_start_time timestamp with time zone, virtual_transaction_id text, transaction_id bigint, query_id bigint, module text, error_severity text, sql_state_code text, message text, detail text, hint text, internal_query text, internal_query_pos integer, context text, query text, query_pos integer, location text, application_name text ); 详细说明请参见表1。 表1 csvlog字段含义表 字段名 字段含义 字段名 字段含义 log_time 毫秒级的时间戳 module 日志所属模块 node_name 节点名称 error_severity ERRORSTATE代码 user_name 用户名 sql_state_code SQLSTATE代码 database_name 数据库名 message 错误消息 process_id 进程ID detail 详细错误消息 connection_from 客户主机:端口号 hint 提示 session_id 会话ID internal_query 内部查询(查询那些导致错误的信息,如果有的话) session_line_num 每个会话的行数 internal_query_pos 内部查询指针 command_tag 命令标签 context 环境 session_start_time 会话开始时间 query 错误发生位置的字符统计 virtual_transaction_id 常规事务 query_pos 错误发生位置指针 transaction_id 事务ID location 在GaussDB源代码中错误的位置(如果log_error_verbosity的值设为verbose ) query_id 查询ID application_name 应用名称 使用COPY FROM命令将日志文件导入这个表: 1 COPY postgres_log FROM '/opt/data/pg_log/logfile.csv' WITH csv; 此处的日志名“logfile.csv”要换成实际生成的日志的名称。
  • 调优手段之GUC参数 查询优化的主要目的是为查询语句选择高效的执行方式。 如下SQL语句: 1 2 select count(1) from customer inner join store_sales on (ss_customer_sk = c_customer_sk); 在执行customer inner join store_sales的时候,GaussDB支持Nested Loop、Merge Join和Hash Join三种不同的Join方式。优化器会根据表customer和表store_sales的统计信息估算结果集的大小以及每种Join方式的执行代价,然后对比选出执行代价最小的执行计划。 正如前面所说,执行代价计算都是基于一定的模型和统计信息进行估算,当因为某些原因代价估算不能反映真实的cost的时候,我们就需要通过GUC参数设置的方式让执行计划倾向更优规划。例如:random_page_cost参数表示优化器计算一次非顺序抓取磁盘页面的开销,该参数默认值为4。当机器磁盘随机读取的速度较快时,比如SSD设备,可以将该参数的值适当调小,更改后,索引扫描的代价降低,生成计划时更倾向于选择索引扫描的方式。
  • 参数说明 connection_target 以下列形式之一指定连接的目标服务器: [ database_name ] [ @host ] [ :port ]:通过TCP/IP连接。 unix:postgresql://host [ :port ] / [ database_name ] [ ?connection_option ]:通过Unix域套接字连接。 tcp:postgresql://host [ :port ] / [ database_name ] [ ?connection_option ]:通过TCP/IP连接。 SQL string constant:包含上述形式之一的值。 connection_name 用于该连接的一个可选标识符,可以在其他命令中引用它。可以是一个SQL标识符或者一个宿主变量。 connection_user 用于数据库连接的用户名。 使用user_name/password、user_name SQLIDENTIFIED BY password或者user_name USING password之一,这个参数也能指定用户名和口令。 用户名和口令可以是SQL标识符、字符串常量或者宿主变量。 上述参数中斜体部分为变量,请根据实际情况进行修改。
  • 示例 Synonym词典可用于解决语言学相关问题,例如,为避免使单词"Paris"变成"pari",可在Synonym词典文件中定义一行"Paris paris",并将该词典放置在预定义的english_stem词典之前。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 gaussdb=# SELECT * FROM ts_debug('english', 'Paris'); alias | description | token | dictionaries | dictionary | lexemes -----------+-----------------+-------+----------------+--------------+--------- asciiword | Word, all ASCII | Paris | {english_stem} | english_stem | {pari} (1 row) gaussdb=# CREATE TEXT SEARCH DICTIONARY my_synonym ( TEMPLATE = synonym, SYNONYMS = my_synonyms, FILEPATH = 'file:///home/dicts/' ); gaussdb=# ALTER TEXT SEARCH CONFIGURATION english ALTER MAPPING FOR asciiword WITH my_synonym, english_stem; gaussdb=# SELECT * FROM ts_debug('english', 'Paris'); alias | description | token | dictionaries | dictionary | lexemes -----------+-----------------+-------+---------------------------+------------+--------- asciiword | Word, all ASCII | Paris | {my_synonym,english_stem} | my_synonym | {paris} (1 row) gaussdb=# SELECT * FROM ts_debug('english', 'paris'); alias | description | token | dictionaries | dictionary | lexemes -----------+-----------------+-------+---------------------------+------------+--------- asciiword | Word, all ASCII | Paris | {my_synonym,english_stem} | my_synonym | {paris} (1 row) gaussdb=# ALTER TEXT SEARCH DICTIONARY my_synonym ( CASESENSITIVE=true); gaussdb=# SELECT * FROM ts_debug('english', 'Paris'); alias | description | token | dictionaries | dictionary | lexemes -----------+-----------------+-------+---------------------------+------------+--------- asciiword | Word, all ASCII | Paris | {my_synonym,english_stem} | my_synonym | {paris} (1 row) gaussdb=# SELECT * FROM ts_debug('english', 'paris'); alias | description | token | dictionaries | dictionary | lexemes -----------+-----------------+-------+---------------------------+------------+--------- asciiword | Word, all ASCII | Paris | {my_synonym,english_stem} | my_synonym | {pari} (1 row) 其中,同义词词典文件全名为my_synonyms.syn,所在目录为当前连接CN节点的/home/dicts/下。关于创建词典的语法和更多参数,请参见CREATE TEXT SEARCH DICTIONARY。 星号(*)可用于词典文件中的同义词结尾,表示该同义词是一个前缀。在to_tsvector()中该星号将被忽略,但在to_tsquery()中会匹配该前缀并对应输出结果(参照处理查询一节)。 假设词典文件synonym_sample.syn内容如下: 1 2 gogle googl indices index* 创建并使用词典: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 gaussdb=# CREATE TEXT SEARCH DICTIONARY syn ( TEMPLATE = synonym, SYNONYMS = synonym_sample ); gaussdb=# SELECT ts_lexize('syn','indices'); ts_lexize ----------- {index} (1 row) gaussdb=# CREATE TEXT SEARCH CONFIGURATION tst (copy=simple); gaussdb=# ALTER TEXT SEARCH CONFIGURATION tst ALTER MAPPING FOR asciiword WITH syn; gaussdb=# SELECT to_tsvector('tst','indices'); to_tsvector ------------- 'index':1 (1 row) gaussdb=# SELECT to_tsquery('tst','indices'); to_tsquery ------------ 'index':* (1 row) gaussdb=# SELECT 'indexes are very useful'::tsvector; tsvector --------------------------------- 'are' 'indexes' 'useful' 'very' (1 row) gaussdb=# SELECT 'indexes are very useful'::tsvector @@ to_tsquery('tst','indices'); ?column? ---------- t (1 row)
共100000条