• [其他] 【升级】升级报错sequence找不到
    问题描述问题标题:向8.0升级过程中报错GTM上sequence找不到【机制说明】由于8.0以前的版本的seq在gtm上存储的信息比较多,alter操作等将会导致gtm上的sequence信息残留以及有可能出现gtm上sequence丢失。【闭环方案】所以GTM上的sequence需要从数据库的CN去恢复,查找所有使用该sequence的表,去最大值+20000当做该sequence修复后的当前值【恢复方案】第一:在所有数据库上创建一下函数create or replace procedure find_seq(dbname text)asseq_name    varchar(1000);tablename   varchar(1000);columnname  varchar(1000);schemanname varchar(1000);schmaname   varchar(1000);        rel_oid     Oid;        adnum       int;cur_max_seq int;max_seq     int;start_value bigint;increment_by bigint;max_value bigint;min_value bigint;cache_value bigint;is_cycled  bool;is_cycled_str char(1);is_called  bool;is_called_str char(1);        type ref_cur_type is ref cursor;        my_cur ref_cur_type;              my_cur_seq_name ref_cur_type;        my_cur_rel_att_name ref_cur_type;        my_cur_max_seq_num ref_cur_type;my_seq_info ref_cur_type;        sqlstr varchar(1000);sqlstr2 varchar(2560);sqlstr3 varchar(2560);sqlstr4 varchar(2560);begin    open my_cur for 'select c.relname, n.nspname from pg_class c, pg_namespace n where c.relnamespace = n.oid AND c.relkind = ''S''';    fetch my_cur into seq_name, schmaname;    while my_cur%found loop        -- dbms_output.put_line(seq_name);        max_seq = 0;        sqlstr='select adrelid, adnum from pg_attrdef where adsrc like ''%' || seq_name || '%''';        open my_cur_seq_name for sqlstr;        fetch my_cur_seq_name into rel_oid, adnum;        while my_cur_seq_name%found loop            -- dbms_output.put_line('-> ('||rel_oid || ' , ' || adnum || ')');            cur_max_seq = 0;sqlstr2  = 'select c.relname as tablename, a.attname, n.nspname as columname from pg_class c, pg_attribute a, pg_namespace n where c.relnamespace = n.oid and c.oid = a.attrelid and a.attrelid = ' || rel_oid || ' and a.attnum = ' || adnum || ';';open my_cur_rel_att_name for sqlstr2;fetch my_cur_rel_att_name into tablename, columnname, schemanname;while my_cur_rel_att_name%found loop--     dbms_output.put_line('-> ('|| tablename || ' , ' || columnname || ')');sqlstr3 = 'select max(' || columnname || ') from ' || schemanname || '.' ||tablename || ';';open my_cur_max_seq_num for sqlstr3;fetch my_cur_max_seq_num into cur_max_seq;    if (cur_max_seq > max_seq) then       max_seq = cur_max_seq;    end if;close my_cur_max_seq_num;     fetch my_cur_rel_att_name into tablename, columnname;end loop;close my_cur_rel_att_name;            fetch my_cur_seq_name into rel_oid, adnum;        end loop;        close my_cur_seq_name;-- dbms_output.put_line(seq_name || ' max value : ' || max_seq);sqlstr4 = 'select start_value, increment_by, max_value, min_value, cache_value, is_cycled, is_called from ' || schmaname || '.' || seq_name;open my_seq_info for sqlstr4;fetch my_seq_info into start_value, increment_by, max_value, min_value, cache_value, is_cycled, is_called;while my_seq_info%found loop if (is_cycled) thenis_cycled_str = 't';elseis_cycled_str = 'f';end if;is_called_str = 't';max_seq = max_seq + 20000;    dbms_output.put_line(dbname || '.'|| schmaname || '.' ||seq_name || '\00' || E'\t' || max_seq || E'\t' || start_value || E'\t' || increment_by || E'\t' || min_value || E'\t'|| max_value || E'\t' || is_cycled_str || E'\t' || is_called_str || E'\t' || '1');fetch my_seq_info into start_value, increment_by, max_value, min_value, cache_value, is_cycled, is_called;   end loop;close my_seq_info;        fetch my_cur into seq_name, schmaname;    end loop;    close my_cur;end;/第二:获取所有数据库列表 使用集群操作先 source 环境变量,下同 source /opt/huawei/Bigdata/mppdb/.mppdbgs_profilegsql -p 25308 postgres -r -t -c "select datname from pg_database where datname not in ('template1', 'template0', 'template2', 'information_schema');" > datname.txt 第3:生成新的sequence信息cat datname.txt | while read LINE       doif [ -z "$LINE" ]; thenecho "skip"elsegsql -p 25308 $LINE -r -c "call find_seq('$LINE');" 2>gtm_contrl.txt.$LINEfi    done 第四:停止主备gtm(主备两个节点)cm_ctl stop -n "" -D gtmpath第五:重建gtm.control文件1. 备份gtm.control文件2. 保存gtm.control文件的前3行信息head -n 3 gtm.control > gtm.control.tmp3. sequence 同步到gtm.control.tmcat datname.txt | while read LINEdo      if [ -z "$LINE" ]; thenecho "skip"elsecat gtm_contrl.txt.$LINE >> gtm.control.tmpfidone 第六:发送gtm.control.tmp到gtm的主备目录scp gtm.control.tmp ...第七:启动gtm节点(主备两个节点)cm_ctl start -n "" -D datapath
  • [热门活动] [获奖名单已公示] 玩转PB级分布式数仓GaussDB(DWS)性能调优黑科技直播,回帖互动报名即可赢大奖!!!
    【直播主题和时间】玩转PB级分布式数仓性能调优黑科技2020年10月20日20:00-21:00【活动介绍】本期DevRun开发者沙龙,华为云数仓GaussDB(DWS) 资深优化器专家&调优大师增哥将带大家玩转PB级分布式数仓GaussDB(DWS)性能调优黑科技。凡在本主题帖中留言、参与直播互动或者论坛互动的用户均可参与抽奖,华为手环,蓝牙音箱,移动电源,华为云定制T-shirt等多重好礼等你来拿~【直播地址和报名入口】点击下面链接或扫描图中二维码报名参加直播。直播链接:https://vhall.huawei.com/fe/watch/6305【互动方式】(以下互动方式任选一种或多种)(互动时间截止到10月28日24:00,奖品会在10月30日公布哦)(1)报名参加本次直播;(2)在本主题帖中跟帖盖楼,留言“玩转数仓GaussDB(DWS)性能调优黑科技”;(3)在本主题帖中跟帖留言(包括但不限于直播收获、数仓产品体验感受、平台建议等);(4)直播互动评论或完成直播调查问卷;(5)在GaussDB(DWS)论坛上发帖互动(问题求助,博文分享,问题解答,产品体验感受,产品优化建议等);(6)在华为云社区分享博文;(7)参与GuassDB(DWS)产品体验测试。【抽奖方式】1.      幸运互动奖:参与方式: 以上互动方式任选一种或多种参与获奖人数:5名奖励:华为云定制T-shirt 评奖规则:参与华为云社区互动或和直播互动即有机会抽取华为云定制T-shirt。2.优秀评论奖: 直播评论或者跟帖留言用户中选出3名优秀评论奖。 获奖人数:3名奖励:华为nova mini蓝牙音箱(颜色随机)评奖规则:活动结束后从回帖留言用户中评选出3名优秀建议奖(包含参与互动话题)。【参与互动】(可参考以下内容任选一个或多个进行回帖)1.留下您对本次直播的疑问,不限技术,我们都将一一作答2.发表直播观后感3. 回复测试环境验证任意截图 (验证代码及造数脚本请参考附件,基础操作帮助文档及视频请参考华为云数据仓库知识地图)回帖示例:  直播观后感例如:本次直播不但学到了知识还可以…… 3.最佳人气奖:移动电源(先到先得)或华为云定制T-shirt参与方式:参与回帖,并分享邀请小伙伴给自己的回帖进行评论+点赞,在人气高的评论或帖子中抽选若干名奖励:华为定制T-shirt/华为20000mAh移动电源获奖总人数:10名评奖规则:活动结束后按照评论+点赞数进行排序(三部移动电源,先到先得) 4.优秀博文奖:手环1个获奖人数:1名奖励:华为手环评奖规则:1、与直播主题相关 2、有一定技术干货  3、将博文链接作为回帖,活动结束后,会有工作人员从论坛(碎片空间或者精品大作)或者博客中,评选出优秀博文。5. 最佳体验奖获奖人数:3名奖励:1000测试劵+华为三脚架带蓝牙自拍杆/《极简人工智能》书籍评奖规则:活动结束后,回帖申请GaussDB DWS 500元测试券,并进行初步体验,完成所布置的题目,选择三名积极参与并提问的小伙伴获得奖励提醒:测试券使用过程中,如果金额使用完毕,集群未删除会产生欠费,强烈建立费用快结束的时候删除集群。【注意事项】1.获奖结果将在活动结束后5个工作日内进行公示,所有奖品将在活动结束后十五个工作日内发放。2.为防止有恶意发帖行为,同一ID回帖不得超过5条,若超过将取消获奖资格。3.每个ID只能参与一次评选,同一ID不可重复中奖。4.本次回帖内容需满足华为云论坛发帖规范 https://bbs.huaweicloud.com/forum/thread-23077-1-1.html小伙伴们,还在等什么,快快盖楼互动赢大奖吧!!!------------------------------------------------------------------------------------------------------------------------------------------------本期玩转PB级分布式数仓GaussDB(DWS)性能调优黑科技直播互动活动已经结束,感谢各位小伙伴的参与!获得本期玩转PB级分布式数仓GaussDB(DWS)性能调优黑科技直播互动奖励的名单如下,恭喜一下小伙伴~请各位中奖的小伙伴到下面链接反馈收货信息哦^_^  请小伙伴们在2020年11月20日前到下面链接反馈收货信息,逾期礼品作废哦^_^ https://bbs.huaweicloud.com/forum/forum.php?mod=viewthread&tid=87226&page=1&extra=#pid452669 【获奖名单】(没有反馈地址的小伙伴快快私信版主反馈获奖地址吧~)奖项中奖人账号/昵称奖品中奖人邮寄地址尺寸幸运互动奖visitor_9675001华为云定制T-shirt已收到幸运互动奖152813袁培仁华为云定制T-shirt已收到幸运互动奖127713徐华为云定制T-shirt已收到幸运互动奖153649郑勇华为云定制T-shirt已收到幸运互动奖137351赵兴旺华为云定制T-shirt待反馈最佳人气奖13811216834华为云定制T-shirt待反馈优秀评论奖153396景晨华为nova mini蓝牙音箱已收到最佳人气奖18510332582华为云定制T-shirt已收到最佳人气奖visitor_8861054华为云定制T-shirt已收到最佳人气奖13516078375华为云定制T-shirt已收到最佳人气奖13752951950华为云定制T-shirt已收到最佳人气奖问道华为云定制T-shirt待反馈最佳人气奖emilyleungbaby华为云定制T-shirt待反馈优秀评论奖帕加尼风之子8866华为nova mini蓝牙音箱已收到最佳人气奖小松鼠华为云定制T-shirt待反馈最佳人气奖神的孩子全跳舞华为云定制T-shirt已收到最佳人气奖152*****608华为云定制T-shirt待反馈优秀评论奖138*****174华为nova mini蓝牙音箱待反馈最佳人气奖狼人移动电源待反馈最佳人气奖爱你一生移动电源待反馈最佳人气奖hw47969246移动电源待反馈
  • [技术原理] ORACLE 触发器在GaussDB(DWS)上的实现
    【摘要】 在GaussDB(DWS)上实现ORACLE的触发器近期项目中遇到客户需要在GaussDB(DWS)上实现ORACLE的触发器。此博文记录一下实现过程。DSC工具转换后,需要手工调整一般SQL语句在ORACLE转换GaussDB(DWS)通过DSC工具转换后,能够直接执行。但触发器转换后,没办法直接执行。参考原来处理的代码,此处整理一个简单的ORACLE的Trigger,然后通过DSC转换后的代码oracle源码CREATE TABLE ORDERS (O_ORDERKEY       INT NOT NULL); CREATE TABLE LINEITEM(L_ORDERKEY    INT NOT NULL, L_PARTKEY     INT NOT NULL); --建触发器 CREATE OR REPLACE TRIGGER  TEST_TRIGGER AFTER INSERT ON ORDERS FOR EACH ROW DECLARE V_O_ORDERKEY INT; begin   V_O_ORDERKEY := :new.O_ORDERKEY;   INSERT INTO LINEITEM VALUES(:new.O_ORDERKEY,1); END test_trigger; /建好触发器后,可以测试一下功能,往ORDERS插入一条数据,看LINEITEM会否有数据插入INSERT INTO ORDERS VALUES (1); SELECT * FROM LINEITEM;DSC转换后CREATE      TABLE           ORDERS (                O_ORDERKEY INT NOT NULL           ) ; CREATE      TABLE           LINEITEM (                L_ORDERKEY INT NOT NULL                ,L_PARTKEY INT NOT NULL           ) ; CREATE OR replace TRIGGER test_trigger AFTER INSERT           ON ORDERS FOR EACH row DECLARE V_O_ORDERKEY INT ; BEGIN V_O_ORDERKEY := :new.O_ORDERKEY ; INSERT      INTO           LINEITEM           VALUES (                :new.O_ORDERKEY                ,1           ) ; END test_trigger ;读者可以尝试拿着这个语句去试跑一下,转换后的语句是需要修改的。DSC转换后修改点1将FOR EACH ROW后面的存储过程内容放到一个函数中,例子如下:create OR replace function test_trigger() returns trigger as $$ DECLARE V_O_ORDERKEY INT ; BEGIN V_O_ORDERKEY := :new.O_ORDERKEY ; INSERT      INTO           LINEITEM           VALUES (                :new.O_ORDERKEY                ,1           ) ; END ;  $$ LANGUAGE plpgsql VOLATILE;然后再建触发器,原文的OR replace去掉,不然会报错CREATE  TRIGGER test_trigger AFTER INSERT           ON ORDERS FOR EACH row  execute procedure  test_trigger();建好触发器后,可以测试一下功能,往ORDERS插入一条数据,看LINEITEM会否有数据插入INSERT INTO ORDERS VALUES (1); SELECT * FROM LINEITEM;GaussDB(DWS)会报如下错误,此时就需要进行修改了DSC转换后修改点2报错的因为ORACLE的触发器中新一行的参数为:new ,而GaussDB(DWS)的新一行参数是不需要冒号:的。所以将函数中:new的:去掉create OR replace function test_trigger() returns trigger as $$ DECLARE V_O_ORDERKEY INT ; BEGIN V_O_ORDERKEY := new.O_ORDERKEY ; INSERT      INTO           LINEITEM           VALUES (                new.O_ORDERKEY                ,1           ) ; END ;  $$ LANGUAGE plpgsql VOLATILE;往ORDERS插入一条数据,看LINEITEM会否有数据插入INSERT INTO ORDERS VALUES (1); SELECT * FROM LINEITEM;发现还是会报错,说没有return值,此处在END前面增加一个RETURN NULL;create OR replace function test_trigger() returns trigger as $$ DECLARE V_O_ORDERKEY INT ; BEGIN V_O_ORDERKEY := new.O_ORDERKEY ; INSERT      INTO           LINEITEM           VALUES (                new.O_ORDERKEY                ,1           ) ; RETURN NULL; END ;  $$ LANGUAGE plpgsql VOLATILE;此时没有报错,触发器也成功实现了功能。实现功能后的优化触发器触发后,执行的一般都是单行条件的SQL。所以要注意建索引,让SQL走indexscan+nestloop的执行计划。但之前遇到的一个情况,就是建了索引以后也存在扫描全表的情况,这样会使触发器执行的很慢。当时遇到的情况是5个表关联,多个表关联可能让执行计划误判,例如A.COL1=B.COL1 .... AND A.COL1=NEW.COL1 这样的关联条件,当时的情况就是B表扫描全表。此处可以等价地增加B表的过滤,例如A.COL1=B.COL1 .... AND A.COL1=NEW.COL1 AND B.COL1 = NEW.COL1 这样的话执行计划就知道走索引扫描了。或者使用hint的方式让B表直接走indexscan。总结ORACLE的触发器是能在GaussDB(DWS)上实现的,但是通过DSC转换工具后,需要进行一定的改写。而触发器的性能不会特别慢,主要基于触发后执行的SQL执行的快慢。之前的经验是触发一个多个大表关联的merge into 语句,插入1000条记录花费的时间是20秒。
  • [技术原理] GaussDB for DWS性能调优系列实际操作篇一:坏味道SQL识别
    【摘要】 GaussDB在执行SQL语句时,会对其性能表现进行分析和记录,通过视图和函数等手段呈现给用户。本文将简要介绍如何利用GaussDB提供的这些“第一手”数据,分析和定位SQL语句中存在的性能问题,识别和消除SQL中的“坏味道”。         SQL语言是关系型数据库(RDB)的标准语言,其作用是将使用者的意图翻译成数据库能够理解的语言来执行。人类之间进行交流时,同样的意思用不同的措辞会产生不同的效果。类似地,人类与数据库交流信息时,同样的操作用不同的SQL语句来表达,也会导致不同的效率。而有时同样的SQL语句,数据库采用不同的方式来执行,效率也会不同。那些会导致执行效率低下的SQL语句及其执行方式,我们称之为SQL中的“坏味道”。         下面这个简单的例子,可以说明什么是SQL中的坏味道。图1-a 用union合并集合         在上面的查询语句中,由于使用了union来合并两个结果集,在合并后需要排序和去重,增加了开销。实际上符合dept_id = 1和dept_id > 2的结果间不会有重叠,所以完全可以用union all来合并,如下图所示。图1-b 用union all合并集合         而更高效的做法是用or条件,在扫描的时候直接过滤出所需的结果,不但节省了运算,也节省了保存中间结果所需的内存开销,如下图所示。图1-c 用or条件来过滤结果         可见完成同样的操作,用不同的SQL语句,效率却大相径庭。前两条SQL语句都不同程度地存在着“坏味道”。         对于这种简单的例子,用户可以很容易发现问题并选出最佳方案。但对于一些复杂的SQL语句,其性能缺陷可能很隐蔽,需要深入分析才有可能挖掘出来。这对数据库的使用者提出了很高的要求。即便是资深的数据库专家,有时也很难找出性能劣化的原因。         GaussDB在执行SQL语句时,会对其性能表现进行分析和记录,通过视图和函数等手段呈现给用户。本文将简要介绍如何利用GaussDB提供的这些“第一手”数据,分析和定位SQL语句中存在的性能问题,识别和消除SQL中的“坏味道”。 ◆ 识别SQL坏味道之自诊断视图         GaussDB在执行SQL时,会对执行计划以及执行过程中的资源消耗进行记录和分析,如果发现异常情况还会记录告警信息,用于对原因进行“自诊断”。用户可以通过下面的视图查询这些信息:•       gs_wlm_session_info•       pgxc_wlm_session_info•       gs_wlm_session_history•       pgxc_wlm_session_history         其中gs_wlm_session_info是基本表,其余3个都是视图。gs_开头的用于查看当前CN节点上收集的信息,pgxc_开头的则包含集群中所有CN收集的信息。各表格和视图的定义基本相同,如下表所示。表1 自诊断表格&函数字段定义名称类型描述datidoid连接后端的数据库OID。dbnametext连接后端的数据库名称。schemanametext模式的名字。nodenametext语句执行的CN名称。usernametext连接到后端的用户名。application_nametext连接到后端的应用名。client_addrinet连接到后端的客户端的IP地址。 如果此字段是null,它表明通过服务器机器上UNIX套接字连接客户端或者这是内部进程,如autovacuum。client_hostnametext客户端的主机名,这个字段是通过client_addr的反向DNS查找得到。这个字段只有在启动log_hostname且使用IP连接时才非空。client_portinteger客户端用于与后端通讯的TCP端口号,如果使用Unix套接字,则为-1。query_bandtext用于标示作业类型,可通过GUC参数query_band进行设置,默认为空字符串。block_timebigint语句执行前的阻塞时间,包含语句解析和优化时间,单位ms。start_timetimestamp with time zone语句执行的开始时间。finish_timetimestamp with time zone语句执行的结束时间。durationbigint语句实际执行的时间,单位ms。estimate_total_timebigint语句预估执行时间,单位ms。statustext语句执行结束状态:正常为finished,异常为aborted。abort_infotext语句执行结束状态为aborted时显示异常信息。resource_pooltext用户使用的资源池。control_grouptext语句所使用的Cgroup。min_peak_memoryinteger语句在所有DN上的最小内存峰值,单位MB。max_peak_memoryinteger语句在所有DN上的最大内存峰值,单位MB。average_peak_memoryinteger语句执行过程中的内存使用平均值,单位MB。memory_skew_percentinteger语句各DN间的内存使用倾斜率。spill_infotext语句在所有DN上的下盘信息:None:所有DN均未下盘。All: 所有DN均下盘。[a:b]: 数量为b个DN中有a个DN下盘。min_spill_sizeinteger若发生下盘,所有DN上下盘的最小数据量,单位MB,默认为0。max_spill_sizeinteger若发生下盘,所有DN上下盘的最大数据量,单位MB,默认为0。average_spill_sizeinteger若发生下盘,所有DN上下盘的平均数据量,单位MB,默认为0。spill_skew_percentinteger若发生下盘,DN间下盘倾斜率。min_dn_timebigint语句在所有DN上的最小执行时间,单位ms。max_dn_timebigint语句在所有DN上的最大执行时间,单位ms。average_dn_timebigint语句在所有DN上的平均执行时间,单位ms。dntime_skew_percentinteger语句在各DN间的执行时间倾斜率。min_cpu_timebigint语句在所有DN上的最小CPU时间,单位ms。max_cpu_timebigint语句在所有DN上的最大CPU时间,单位ms。total_cpu_timebigint语句在所有DN上的CPU总时间,单位ms。cpu_skew_percentinteger语句在DN间的CPU时间倾斜率。min_peak_iopsinteger语句在所有DN上的每秒最小IO峰值(列存单位是次/s,行存单位是万次/s)。max_peak_iopsinteger语句在所有DN上的每秒最大IO峰值(列存单位是次/s,行存单位是万次/s)。average_peak_iopsinteger语句在所有DN上的每秒平均IO峰值(列存单位是次/s,行存单位是万次/s)。iops_skew_percentinteger语句在DN间的IO倾斜率。warningtext显示告警信息。queryidbigint语句执行使用的内部query   id。querytext执行的语句。query_plantext语句的执行计划。node_grouptext语句所属用户对应的逻辑集群。         其中的query字段就是执行的SQL语句。通过分析每个query对应的各字段,例如执行时间,内存,IO,下盘量和倾斜率等等,可以发现疑似有问题的SQL语句,然后结合query_plan(执行计划)字段,进一步地加以分析。特别地,对于一些在执行过程中发现的异常情况,warning字段还会以human-readable的形式给出告警信息。目前能够提供的自诊断信息如下:◇多列/单列统计信息未收集         优化器依赖于表的统计信息来生成合理的执行计划。如果没有及时对表中各列收集统计信息,可能会影响优化器的判断,从而生成较差的执行计划。如果生成计划时发现某个表的单列或多列统计信息未收集,warning字段会给出如下告警信息:Statistic Not Collect:schemaname.tablename(column name list)         此外,如果表格的统计信息已收集过(执行过analyze),但是距离上次analyze时间较远,表格内容发生了很大变化,可能使优化器依赖的统计信息不准,无法生成最优的查询计划。针对这种情况,可以用pg_total_autovac_tuples系统函数查询表格中自从上次分析以来发生变化的元组的数量。如果数量较大,最好执行一下analyze以使优化器获得最新的统计信息。 ◇SQL未下推         执行计划中的算子,如果能下推到DN节点执行,则只能在CN上执行。因为CN的数量远小于DN,大量操作堆积在CN上执行,会影响整体性能。如果遇到不能下推的函数或语法,warning字段会给出如下告警信息:SQL is not plan-shipping, reason : %s ◇Hash连接大表做内表         如果发现在进行Hash连接时使用了大表作为内表,会给出如下告警信息:PlanNode[%d] Large Table is INNER in HashJoin \"%s\"目前“大表”的标准是平均每个DN上的行数大于100,000,并且内表行数是外表行数的10倍以上。 ◇大表等值连接使用NestLoop         如果发现对大表做等值连接时使用了NestLoop方式,会给出如下告警信息:PlanNode[%d] Large Table with Equal-Condition use Nestloop\"%s\"目前大表等值连接的判断标准是内表和外表中行数最大者大于DN的数量乘以100,000。 ◇数据倾斜         数据在DN之间分布不均匀,可导致数据较多的节点成为性能瓶颈。如果发现数据倾斜严重,会给出如下告警信息:PlanNode[%d] DataSkew:\"%s\", min_dn_tuples:%.0f, max_dn_tuples:%.0f目前数据倾斜的判断标准是DN中行数最多者是最少者的10倍以上,且最多者大于100,000。 ◇代价估算不准确         GaussDB在执行SQL语句过程中会统计实际付出的代价,并与之前估计的代价比较。如果优化器对代价的估算与实际的偏差很大,则很可能生成一个非最优化的计划。如果发现代价估计不准确,会给出如下告警信息:"PlanNode[%d] Inaccurate Estimation-Rows: \"%s\" A-Rows:%.0f, E-Rows:%.0f目前的代价由计划节点返回行数来衡量,如果平均每个DN上实际/估计返回行数大于100,000,并且二者相差10倍以上,则认定为代价估算不准。 ◇Broadcast量过大         Broadcast主要适合小表。对于大表来说,通常采用Hash+重分布(Redistribute)的方式效率更高。如果发现计划中有大表被广播的环节,会给出如下告警信息:PlanNode[%d] Large Table in Broadcast \"%s\"目前对大表广播的认定标准为平均广播到每个DN上的数据行数大于100,000。 ◇索引设置不合理  如果对索引的使用不合理,比如应该采用索引扫描的地方却采用了顺序扫描,或者应该采用顺序扫描的地方却采用了索引扫描,可能会导致性能低下。索引扫描的价值在于减少数据读取量,因此认为索引扫描过滤掉的行数越多越好。如果采用索引扫描,但输出行数/扫描总行数>1/1000,并且输出行数>10000(对于行存表)或>100(对于列存表),则会给出如下告警信息:PlanNode[%d] Indexscan is not properly used:\"%s\", output:%.0f, filtered:%.0f, rate:%.5f顺序扫描适用于过滤的行数占总行数比例不大的情形。如果采用顺序扫描,但输出行数/扫描总行数<=1/1000,并且输出行数<=10000(对于行存表)或<=100(对于列存表),则会给出如下告警信息:PlanNode[%d] Indexscan is ought to be used:\"%s\", output:%.0f, filtered:%.0f, rate:%.5f ◇下盘量过大或过早下盘         SQL语句执行过程中,因为内存不足等原因,可能需要将中间结果的全部或一部分转储的磁盘上。下盘可能导致性能低下,应该尽量避免。如果监测到下盘量过大或过早下盘等情况,会给出如下告警信息:•       Spill file size large than 256MB•       Broadcast size large than 100MB•       Early spill•       Spill times is greater than 3•       Spill on memory adaptive•       Hash table conflict         下盘可能是因为缓冲区设置得过小,也可能是因为表的连接顺序或连接方式不合理等原因,要结合具体的SQL进行分析。可以通过改写SQL语句,或者HINT指定连接方式等手段来解决。          使用自诊断视图功能,需要将以下变量设成合适的值:▲ use_workload_manager(设成on,默认为on)▲ enable_resource_check(设成on,默认为on)▲ resource_track_level(如果设成query,则收集query级别的信息,如果设成operator,则收集所有信息,如果设成none,则以用户默认的log级别为准)▲ resource_track_cost(设成合适的正整数。为了不影响性能,只有执行代价大于resource_track_cost语句才会被收集。该值越大,收集的语句越少,对性能影响越小;反之越小,收集的语句越多,对性能的影响越大。)         执行完一条代价大于resource_track_cost后,诊断信息会存放在内存hash表中,可通过pgxc_wlm_session_history或gs_wlm_session_history视图查看。         视图中记录的有效期是3分钟,过期的记录会被系统清理。如果设置enable_resource_record=on,视图中的记录每隔3分钟会被转储到gs_wlm_session_info表中,因此3分钟之前的历史记录可以通过gs_wlm_session_info表或pgxc_wlm_session_info视图查看。  ◆ 发现正在运行的SQL的坏味道         上一节提到的自诊断视图可以显示已完成SQL的信息。如果要查看正在运行的SQL的情况,可以使用下面的视图:•       gs_wlm_session_statistics•       pgxc_wlm_session_statistics         类似地,gs_开头的用于查看当前CN节点上收集的信息,pgxc_开头的则包含集群中所有CN收集的信息。两个视图的定义与上一节的自诊断视图基本相同,使用方法也基本一致。 通过观察其中的字段,可以发现正在运行的SQL中存在的性能问题。         例如,通过“select queryid, duration from gs_wlm_session_statistics order by duration desc limit 10;”可以查询当前运行的SQL中,已经执行时间最长的10个SQL。如果时间过长,可能有必要分析一下原因。图2-a 通过gs_wlm_session_statistics视图发现可能hang住SQL         查到queryid后,可以通过query_plan字段查看该SQL的执行计划,分析其中可能存在的性能瓶颈和异常点。图2-b 通过gs_wlm_session_statistics视图查看当前SQL的执行计划         再下一步,可以结合等待视图等其他手段定位性能劣化的原因。图2-c 通过gs_wlm_session_statistics视图结合等待视图定位性能问题         另外,活动视图pg_stat_activity也能提供一些当前执行SQL的信息。 ◆ Top SQL——利用统计信息发现SQL坏味道         除了针对逐条SQL进行分析,还可以利用统计信息发现SQL中的坏味道。另一篇文章“Unique SQL特性原理与应用”中提到的Unique SQL特性,能够针对执行计划相同的一类SQL进行了性能统计。与自诊断视图不同的是,如果同一个SQL被多次执行,或者多个SQL语句的结构相同,只有条件中的常量值不同。这些SQL在Unique SQL视图中会合并为一条记录。因此使用Unique SQL视图能更容易看出那些类型的SQL语句存在性能问题。         利用这一特性,可以找出某一指标或者某一资源占用量最高/最差的那些SQL类型。这样的SQL被称为“Top SQL”。         例如,查找占用CPU时间最长的SQL语句,可以用如下SQL:select unique_sql_id,query,cpu_time from pgxc_instr_unique_sql order by cpu_time desc limit 10。         Unique SQL的使用方式详见https://bbs.huaweicloud.com/blogs/197299。 ◆ 结论         发现SQL中的坏味道是性能调优的前提。GaussDB对数据库的运行状况进行了SQL级别的监控和记录。这些打点记录的数据可以帮助用户发现可能存在的异常情况,“嗅”出潜在的坏味道。从这些数据和提示信息出发,结合其他视图和工具,可以定位出坏味道的来源,进而有针对性地进行优化。【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区),文章链接,文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件至:huaweicloud.bbs@huawei.com进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容。
总条数:19 到第
上滑加载中