云服务器内容精选

  • checkpoint_segments 参数说明:设置checkpoint_timeout周期内所保留的最少WAL日志段文件数量。每个日志文件大小为16MB。 参数类型:SIGHUP 取值范围:整型,最小值1。 默认值:64 提升此参数可加快大数据的导入速度,但需要结合checkpoint_timeout、shared_buffers这两个参数统一考虑。这个参数同时影响WAL日志段文件复用数量,通常情况下pg_xlog文件夹下最大的复用文件个数为2倍的checkpoint_segments个,复用的文件被改名为后续即将使用的WAL日志段文件,不会被真正删除。
  • autovacuum_max_workers_hstore 参数说明:设置Autovacuum_max_workers里面,能同时运行的专用于清理hstore的自动清理线程的最大数量。 参数类型:SIGHUP 取值范围:整型 默认值:0 当需要使用hstore表时,一定要同步修改以下参数的默认值,否则会导致hstore表性能严重劣化,推荐的修改配置是: autovacuum_max_workers_hstore=3,autovacuum_max_workers=6,autovacuum=true。
  • track_sql_count 参数说明:控制对每个会话中当前正在执行的SELECT、INSERT、UPDATE、DELETE、MERGE INTO语句是否进行计数统计,对SELECT、INSERT、UPDATE、DELETE语句的响应时间进行统计,以及对DDL、DML、DCL语句进行计数的统计。 参数类型:SUSET 取值范围:布尔型 on表示开启统计功能。 off表示关闭统计功能。 默认值:on track_sql_count参数受track_activities约束: track_activities开启而track_sql_count关闭时,如果查询了gs_sql_count、pgxc_sql_count、gs_workload_sql_count、pgxc_workload_sql_count、global_workload_sql_count、gs_workload_sql_elapse_time、pgxc_workload_sql_elapse_time或global_workload_sql_elapse_time视图,将会有 LOG 提示track_sql_count是关闭的。 track_activities和track_sql_count同时关闭,那么此时将会有两条LOG,分别提示track_activities是关闭的和track_sql_count是关闭的。 track_activities关闭而track_sql_count开启,此时将仅有LOG提示track_activities是关闭。 当参数关闭时,查询视图的结果为0行。
  • instr_unique_sql_count 参数说明:控制是否收集整个集群的Unique SQL以及收集数量限制。 参数类型:SIGHUP 取值范围:整型,0~ INT_MAX 值为0时,表示不收集Unique SQL统计信息。 值大于0时,在CN节点上,将会控制收集的Unique SQL数量不超过该设置值。当收集数量达到限制时,不再收集新的Unique SQL,此时可通过reload调大设置值,继续收集新的Unique SQL。 默认值:0 如果新设置值小于原设置值,将会清空对应CN节点已收集的Unique SQL统计信息。需特别注意该清理操作将由资源管理后台线程完成,若GUC参数use_workload_manager为off时清理操作可能失败,可直接使用函数reset_instr_unique_sql进行清理。
  • FOR_LOOP(integer变量)语句 语法图 图3 for_loop::= 变量name会自动定义为integer类型并且只在此循环里存在。变量name介于lower_bound和upper_bound之间。 当使用REVERSE关键字时,lower_bound必须大于等于upper_bound,否则循环体不会被执行。 示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 --从0到5进行循环 CREATE OR REPLACE PROCEDURE proc_for_loop() AS BEGIN FOR I IN 0..5 LOOP DBMS_OUTPUT.PUT_LINE('It is '||to_char(I) || ' time;') ; END LOOP; END; / --调用函数 CALL proc_for_loop(); --删除存储过程 DROP PROCEDURE proc_for_loop;
  • FOR_LOOP查询语句 语法图 图4 for_loop_query::= 变量target会自动定义,类型和query的查询结果的类型一致,并且只在此循环中有效。target的取值就是query的查询结果。 示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 --循环输出查询结果。 CREATE OR REPLACE PROCEDURE proc_for_loop_query() AS record VARCHAR2(50); BEGIN FOR record IN SELECT spcname FROM pg_tablespace LOOP dbms_output.put_line(record); END LOOP; END; / --调用函数 CALL proc_for_loop_query(); --删除存储过程 DROP PROCEDURE proc_for_loop_query;
  • FORALL批量查询语句 语法图 图5 forall::= 变量index会自动定义为integer类型并且只在此循环里存在。index的取值介于low_bound和upper_bound之间。 示例 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 CREATE TABLE hdfs_t1 ( title NUMBER(6), did VARCHAR2(20), data_period VARCHAR2(25), kind VARCHAR2(25), interval VARCHAR2(20), time DATE, isModified VARCHAR2(10) ) DISTRIBUTE BY hash(did); INSERT INTO hdfs_t1 VALUES( 8, 'Donald', 'OConnell', 'DOCONNEL', '650.507.9833', to_date('21-06-1999', 'dd-mm-yyyy'), 'SH_CLERK' ); CREATE OR REPLACE PROCEDURE proc_forall() AS BEGIN FORALL i IN 100..120 insert into hdfs_t1(title) values(i); END; / --调用函数 CALL proc_forall(); --查询存储过程调用结果 SELECT * FROM hdfs_t1 WHERE title BETWEEN 100 AND 120; --删除存储过程和表 DROP PROCEDURE proc_forall; DROP TABLE hdfs_t1;
  • GS_INSTR_UNIQUE_SQL视图 GS_INSTR_UNIQUE_SQL视图显示当前节点收集的Unique SQL的执行信息,主要包括以下内容: Unique SQL ID以及归一化后的SQL文本字符串,归一化后的SQL文本如示例中所示。通常对于DML语句,在计算Unique SQL ID的过程中会忽略常量值。但对于DDL、DCL以及设置参数等语句,常量值不可以忽略。 执行次数(成功执行的次数),响应时间(数据库内部的SQL执行时间,包括最大、最小和总时间)。 Cache/IO信息,包含block的物理读、逻辑读次数,仅统计执行成功的SQL在各DN节点上的相关信息。该统计值与查询执行当时所处理的数据量、所使用的内存、是否多次执行、内存管理策略、是否有其他并发查询等因素相关,反映整个查询执行过程中的buffer块物理读和逻辑读次数,不同时间执行可能统计值不同。 行活动,包含SELECT语句的结果集返回行数、更新行、插入行、删除行、顺序扫描行、随机扫描行等信息。除结果集返回行数与该SELECT语句的结果集行数一致、且仅在CN上记录外,其他行活动信息均在DN上记录,且统计数值反应的是整个查询执行过程中的行活动,包括对相关系统表、元数据表、数据表等做必要的扫描和修改,与对应数据量以及相关参数设置相关,即统计数值将会大于等于对实际数据表的扫描和修改。 时间分布,包含:DB_TIME/CPU_TIME/EXECUTION_TIME/PARSE_TIME/PLAN_TIME/REWRITE_TIME/PL_EXECUTION_TIME/PL_COMPILATION_TIME/NET_SEND_TIME/DATA_IO_TIME,相关定义见表1。该信息在CN和DN节点均有统计,视图查询时将汇总展示。 软硬解析次数,包含软解析(缓存计划)、硬解析(生成计划)的次数,即如果本次执行的是之前缓存的计划,软解析次数+1,如果本次执行的计划是重新生成的,则硬解析次数+1。该次数在CN和DN节点上都会统计,视图查询时将汇总展示。 Unique SQL收集功能存在以下约束: 只有执行成功的SQL才会显示其详细的统计信息,否则可能只记录query、node、user等信息。 如果开启Unique SQL收集功能,CN节点将对所有接收到的查询进行统计收集,包括工具和用户的查询等。 若一条SQL语句内部包含执行多条SQL语句、类似存储过程执行等场景,仅会对最外层SQL生成一条Unique SQL,所有子SQL的统计信息都会汇总到该Unique SQL记录上。 Unique SQL的响应时间统计中不完全包含NET_SEND_TIME阶段的时间,所以EXECUTION_TIME和elapse_time等时间之间不存在大小比较关系。 对于类似begin;...;commit;等形式的事务块,当前不支持统计子句的解析时间(parse_time)。 普通用户访问GS_INSTR_UNIQUE_SQL视图,只能看到该用户相关的Unique SQL信息,管理员用户可以看到当前节点所有的Unique SQL信息。CN和DN上均可查询GS_INSTR_UNIQUE_SQL视图,DN上显示的是本节点内的Unique SQL统计信息,CN上显示的是本节点Unique SQL完整统计信息,即该CN节点会收集其他CN和DN上对应该CN的Unique SQL的执行信息,进行汇总展示。通过查询GS_INSTR_UNIQUE_SQL视图,能够定位由于消耗不同资源导致的Top SQL,为集群性能调优和维护提供依据。 GUC参数instr_unique_sql_timeout设置了Unique SQL的超时时间,单位是小时。后台线程每隔1小时检查一次所有的Unique SQL,将last_time在instr_unique_sql_timeout小时之前的Unique SQL删除。
  • 总体开发设计规范 下表是 GaussDB (DWS)开发过程中需遵循的开发设计规范全集列表,可以单击链接跳转到对应的规则下了解详细说明。 表1 GaussDB(DWS)开发设计规范全集列表 编号 类别 规则/建议 1 连接管理规范 - 规则1.1 GaussDB(DWS)集群必须配置负载均衡 2 规则1.2 连接数据库完成所需操作后,必须关闭数据库连接(连接池场景除外) 3 规则1.3 开启的事务最后必须提交或回滚 4 规则1.4 应用侧使用连接池场景,其空闲超时配置必须小于服务侧的SESSION_TIMEOUT配置 5 规则1.5 应用侧使用连接池场景,如使用连接SET设置过参数,当将连接归还连接池前,必须进行参数重置 6 规则1.6 应用侧使用连接池场景,如使用连接创建过临时表,当将连接归还连接池前,必须手动清理所创建的临时表 7 对象设计规范 DATABASE对象设计 规则2.1 避免直接使用内置的DATABASE(如postgres、gaussdb等) 8 规则2.2 创建DATABASE时必须选择正确的数据库编码 9 规则2.3 创建DATABASE时必须选择正确的数据库兼容模式 10 建议2.4 存在关联计算的对象放在同一个DATABASE中 11 USER对象设计 规则2.5 禁止使用特殊权限用户运行业务,需遵循权限最小分配原则 12 规则2.6 禁止使用一个数据库用户运行所有业务 13 SCHEMA对象设计 建议2.7 不在其他USER的私有SCHEMA下创建对象 14 TABLESPACE对象设计 规则2.8 禁止自定义TABLESPACE表空间 15 TABLE对象设计(重点) 规则2.9 创建表时必须选择正确的分布方式和分布列 16 规则2.10 创建表时必须选择正确的存储方式 17 规则2.11 创建表时必须选择正确的分区策略 18 建议2.12 表字段的设计要遵循高效、准确原则 19 建议2.13 避免使用自增列或自增数据类型 20 INDEX对象设计(重点) 规则2.14 只创建必要的索引,创建索引必须选择合适的列和顺序 21 建议2.15 列存表通常可不建索引,极致性能场景需正确选择索引类型 22 VIEW对象设计 建议2.16 视图的嵌套需避免超过三层 23 SQL开发规范 DDL操作规范 建议3.1 DDL操作(CREATE除外)避免在业务高峰期和长事务中执行 24 规则3.2 DROP删除对象操作必须明确删除对象范围 25 INSERT操作规范 规则3.3 INSERT多VALUES批插场景使用COPY替代 26 建议3.4 禁止针对普通列存表进行实时INSERT操作 27 UPDATE/DELETE操作规范 建议3.5 避免并发UPDATE/DELETE行存表的同一行 28 建议3.6 避免对列存表频繁或并发执行UPDATE/DELETE 29 SELECT操作(含所有语法中的查询部分)规范 规则3.7 禁止执行不下推的SQL 30 规则3.8 禁止多表关联时缺少关联条件 31 规则3.9 多表关联字段数据类型要保持一致 32 建议3.10 尽量避免对关联条件字段和过滤条件字段进行函数运算 33 建议3.11 资源高消耗型SQL需做好压测和并发管控 34 规则3.12 禁止针对行存大表的频繁COUNT 35 建议3.13 避免查询返回超大结果集(数据导出场景除外) 36 建议3.14 查询时避免使用“SELECT *”写法 37 建议3.15 谨慎使用递归语句(WITH RECURSIVE),明确终止条件,确保递归可终止 38 建议3.16 访问对象(表,函数等)时带上SCHEMA名称 39 建议3.17 针对SQL标记注释,唯一标识SQL的归属 40 建议3.18 SQL语句的长度不要超过64K 41 外表功能开发规范 GDS外表 规则4.1 GDS服务须单独使用服务器部署在DWS集群外 42 协同分析外表 规则4.2 避免同时对多个协同分析外表进行跨集群并发访问 43 存储过程开发规范 - 建议5.1 避免使用复杂的存储过程,避免存储过程嵌套 44 规则5.2 存储过程内需避免执行非CREATE类的DDL操作
  • 其他因素对SMP性能的影响 除了资源因素外,还有一些因素也会对SMP并行性能造成影响。例如分区表中分区数据不均,以及系统并发度等因素。 数据倾斜对SMP性能的影响 当数据中存在严重数据倾斜时,并行效果较差。例如某表join列上某个值的数据量远大于其他值,开启并行后,根据join列的值对该表数据做hash重分布,使得某个并行线程的数据量远多于其他线程,造成长尾问题,导致并行后效果差。 系统并发度对SMP性能的影响 SMP特性会增加资源的使用,而在高并发场景下资源剩余较少。所以,如果在高并发场景下,开启SMP并行,会导致各查询之间严重的资源竞争问题。一旦出现了资源竞争的现象,无论是CPU、I/O、内存或者网络资源,都会导致整体性能的下降。因此在高并发场景下,开启SMP经常不能达到性能提升的效果,甚至可能引起性能劣化。
  • 资源对SMP性能的影响 SMP架构是一种利用富余资源来换取时间的方案,计划并行之后必定会引起资源消耗的增加,包括CPU、内存、I/O和网络带宽等资源的消耗都会出现明显的增长,而且随着并行度的增大,资源消耗也随之增大。当上述资源成为瓶颈的情况下,SMP无法提升性能,反而可能导致集群整体性能的劣化。SMP支持自适应特性,该特性会根据当前资源和查询特征,动态选取最优的并行度。下面对各种资源对SMP性能的影响情况分别进行说明: CPU资源 在一般客户场景中,系统CPU利用率不高的情况下,利用SMP并行架构能够更充分地利用系统CPU资源,提升系统性能。但当数据库服务器的CPU核数较少,CPU利用率已经比较高的情况下,如果打开SMP并行,不仅性能提升不明显,反而可能因为多线程间的资源竞争而导致性能劣化。 内存资源 查询并行后会导致内存使用量的增长,但每个算子使用内存上限仍受到work_mem等参数的限制。假设work_mem为4GB,并行度为2,那么每个并行线程所分到的内存上限为2GB。在work_mem较小或者系统内存不充裕的情况下,使用SMP并行后,可能出现数据下盘,导致查询性能劣化的问题。 网络带宽资源 为了实现查询并行执行,会新增并行线程间的数据交换算子。对于Local类Stream算子,所需要进行数据交换的线程在同一个DN内,通过内存交换,不会增加网络负担。而非Local类算子,需要通过网络进行数据交换,因此会加重网络负担。当网络资源成为瓶颈的情况下,并行可能会导致一定程度的劣化。 I/O资源 要实现并行扫描必定会增加I/O的资源消耗,因此只有在I/O资源充足的情况下,并行扫描才能够提高扫描性能。
  • SMP适用场景与限制 SMP适用场景: 支持并行的算子 计划中存在以下算子支持并行: Scan:支持行存普通表和行存分区表顺序扫描、列存普通表和列存分区表顺序扫描、HDFS内外表顺序扫描;支持GDS数据导入的外表扫描并行。以上均不支持复制表。 Join:HashJoin、NestLoop Agg:HashAgg、SortAgg、PlainAgg、WindowAgg(只支持partition by,不支持order by) Stream:Redistribute、Broadcast 其他:Result、Subqueryscan、Unique、Material、Setop、Append、VectoRow、RowToVec SMP特有算子 为了实现并行,新增了并行线程间的数据交换Stream算子供SMP特性使用。以下新增的算子可以看做Stream算子的子类: Local Gather:实现DN内部并行线程的数据汇总 Local Redistribute:在DN内部各线程之间,按照分布键进行数据重分布 Local Broadcast:将数据广播到DN内部的每个线程 Local RoundRobin:在DN内部各线程之间实现数据轮询分发 Split Redistribute:在集群跨DN的并行线程之间实现数据重分布 Split Broadcast:将数据广播到集群所有DN的并行线程 上述新增算子可以分为Local与非Local两类,Local类算子实现了DN内部并行线程间的数据交换,而非Local类算子实现了跨DN的并行线程间的数据交换。 示例说明 以TPCH Q1的并行计划为例: 在这个计划中,实现了Hdfs Scan以及HashAgg算子的并行,并且新增了Local Gather和Split Redistribute数据交换算子。 其中6号算子为Split Redistribute算子,上面标有的“dop: 4/4”表明Split Redistribute的发送端和接收端线程的并行度均为4。4号算子为Local Gather,上面标有“dop: 1/4”,该算子的发送端线程并行度为4,而接收端线程并行度为1,即下层的5号Hash Aggregate算子按照4并行度执行,而上层的1~3号算子按照串行执行,4号算子实现了DN内并行线程的数据汇总。 通过计划Stream算子上标明的dop信息即可看出各个算子的并行情况。 非适用场景:
  • SMP相关参数配置建议 如果要打开SMP自适应功能,要设置query_dop=0,需同步调整以下相关参数值,以获取更佳的dop选择: comm_usable_memory 当系统内存较大时,max_process_memory设置较大,可适当调大该值,建议设置为max_process_memory的5%,默认值为4GB。 comm_max_stream 设置建议值为:comm_max_stream=Min(dop_limit * dop_limit * 20 * 2, max_process_memory(字节数) * 0.025 / 总DN数 / 260),且该值在comm_max_stream取值范围内。 max_connections 设置建议值为:max_connections=dop_limit * 20 * 6 + 24,且该值在max_connections取值范围内。 公式中的dop_limit为集群中每个DN对应的CPU数,计算公式为:dop_limit = 单机器的CPU逻辑核数 / 单机器的DN数。
  • 存储层数据倾斜 GaussDB(DWS)数据库中,数据分布存储在各个DN上,通过分布式执行提高查询的效率。但是,如果数据分布存在倾斜,则会导致分布式执行某些DN成为瓶颈,影响查询性能。这种情况通常是由于分布列选择不合理,可以通过调整分布列的方式解决。 例如下例: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 explain performance select count(*) from inventory; 5 -- CS tore Scan on lmz.inventory dn_6001_6002 (actual time=0.444..83.127 rows=42000000 loops=1) dn_6003_6004 (actual time=0.512..63.554 rows=27000000 loops=1) dn_6005_6006 (actual time=0.722..99.033 rows=45000000 loops=1) dn_6007_6008 (actual time=0.529..100.379 rows=51000000 loops=1) dn_6009_6010 (actual time=0.382..71.341 rows=36000000 loops=1) dn_6011_6012 (actual time=0.547..100.274 rows=51000000 loops=1) dn_6013_6014 (actual time=0.596..118.289 rows=60000000 loops=1) dn_6015_6016 (actual time=1.057..132.346 rows=63000000 loops=1) dn_6017_6018 (actual time=0.940..110.310 rows=54000000 loops=1) dn_6019_6020 (actual time=0.231..41.198 rows=21000000 loops=1) dn_6021_6022 (actual time=0.927..114.538 rows=54000000 loops=1) dn_6023_6024 (actual time=0.637..118.385 rows=60000000 loops=1) dn_6025_6026 (actual time=0.288..32.240 rows=15000000 loops=1) dn_6027_6028 (actual time=0.566..118.096 rows=60000000 loops=1) dn_6029_6030 (actual time=0.423..82.913 rows=42000000 loops=1) dn_6031_6032 (actual time=0.395..78.103 rows=39000000 loops=1) dn_6033_6034 (actual time=0.376..51.052 rows=24000000 loops=1) dn_6035_6036 (actual time=0.569..79.463 rows=39000000 loops=1) 在performance信息中,可以看到inventory表各DN的scan行数,发现各DN的行数差距较大,最大的为63000000,最小的只有15000000,差了4倍。这个差距对于数据扫描的性能影响还可以接受,但如果上层有join算子,则影响较大。 通常,数据表在各DN上是hash分布的,因此分布列的选择很重要。通过table_skewness()函数来查看上述inventory表在各DN的数据分布倾斜,查询结果如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 select table_skewness('inventory'); table_skewness ------------------------------------------ ("dn_6015_6016 ",63000000,8.046%) ("dn_6013_6014 ",60000000,7.663%) ("dn_6023_6024 ",60000000,7.663%) ("dn_6027_6028 ",60000000,7.663%) ("dn_6017_6018 ",54000000,6.897%) ("dn_6021_6022 ",54000000,6.897%) ("dn_6007_6008 ",51000000,6.513%) ("dn_6011_6012 ",51000000,6.513%) ("dn_6005_6006 ",45000000,5.747%) ("dn_6001_6002 ",42000000,5.364%) ("dn_6029_6030 ",42000000,5.364%) ("dn_6031_6032 ",39000000,4.981%) ("dn_6035_6036 ",39000000,4.981%) ("dn_6009_6010 ",36000000,4.598%) ("dn_6003_6004 ",27000000,3.448%) ("dn_6033_6034 ",24000000,3.065%) ("dn_6019_6020 ",21000000,2.682%) ("dn_6025_6026 ",15000000,1.916%) (18 rows) 通过查询建表定义,可以发现,目前该表是以inv_date_sk作为分布列的,导致存在倾斜。通过查看各列的数据分布情况,改为inv_item_sk作为分布列,则倾斜情况分布如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 select table_skewness('inventory'); table_skewness ------------------------------------------ ("dn_6001_6002 ",43934200,5.611%) ("dn_6007_6008 ",43829420,5.598%) ("dn_6003_6004 ",43781960,5.592%) ("dn_6031_6032 ",43773880,5.591%) ("dn_6033_6034 ",43763280,5.589%) ("dn_6011_6012 ",43683600,5.579%) ("dn_6013_6014 ",43551660,5.562%) ("dn_6027_6028 ",43546340,5.561%) ("dn_6009_6010 ",43508700,5.557%) ("dn_6023_6024 ",43484540,5.554%) ("dn_6019_6020 ",43466800,5.551%) ("dn_6021_6022 ",43458500,5.550%) ("dn_6017_6018 ",43448040,5.549%) ("dn_6015_6016 ",43247700,5.523%) ("dn_6005_6006 ",43200240,5.517%) ("dn_6029_6030 ",43181360,5.515%) ("dn_6025_6026 ",43179700,5.515%) ("dn_6035_6036 ",42960080,5.487%) (18 rows) 数据分布倾斜的问题得到解决。 除了table_skewness()函数外,当前版本还提供了table_distribution函数和PGXC_GET_TABLE_SKEWNESS视图,可以更加高效的查询各表的数据倾斜情况。
  • 语法 语法请参见图1。 图1 call_procedure::= using_clause子句的语法参见图2。 图2 using_clause-3 对以上语法格式的解释如下: CALL procedure_name,调用存储过程。 [:placeholder1,:placeholder2,…],存储过程参数占位符列表,占位符个数与参数个数相同。占位符命名以“:”或“$”开始,“:”后面可跟数字、字符或字符串(不能使用带引号的数字、字符或字符串),“$”后面仅可跟数字。占位符与USING子句的bind_argument一一对应。 USING [IN|OUT|IN OUT] bind_argument,用于指定存放传递给存储过程参数值的变量。bind_argument前的修饰符与对应参数的修饰符一致。