资源监控作业级监控之TopSQL

举报
直线歪了 发表于 2024/12/22 19:10:14 2024/12/22
【摘要】 1、TopSQL简介    在实际的生产环境中,难免会出现一些突发情况,如计划跳变、异常中断、作业长时间执行不结束等,如果已经没有现场,而且也没有工具将当时的作业运行情况记录下来的话,那么事后就要投入更多的人力以及时间成本对错误进行定位和解决,有时还往往定位不到错误出现的地方。为了解决这种情况,GaussDB(DWS)开发了TopSQL功能,对运行中的语句记录(实时TopSQL),对运行完成...

1、TopSQL简介

    在实际的生产环境中,难免会出现一些突发情况,如计划跳变、异常中断、作业长时间执行不结束等,如果已经没有现场,而且也没有工具将当时的作业运行情况记录下来的话,那么事后就要投入更多的人力以及时间成本对错误进行定位和解决,有时还往往定位不到错误出现的地方。为了解决这种情况,GaussDB(DWS)开发了TopSQL功能,对运行中的语句记录(实时TopSQL),对运行完成的语句进行记录(历史TopSQL)。 

    目前TopSQL功能被用户广泛使用,是性能定位、劣化分析、审计回溯等重要的基石,为用户提供覆盖内存、耗时、IO、网络、空间等多方面的监控能力。 TopSQL可以帮助用户实现下列功能:①确定影响数据库性能的资源最密集的SQL查询;②监控和跟踪SQL查询随时间推移的性能变化;③分析查询执行计划以确定潜在的优化。

2、TopSQL相关视图与GUC参数

    TopSQL功能主要通过视图承载,相关视图如下:

视图级别 实时 / 历史 节点范围 查询视图
query级别 / perf级别 实时 当前CN GS_WLM_SESSION_STATISTICS
所有CN PGXC_WLM_SESSION_STATISTICS
历史 当前CN GS_WLM_SESSION_INFO
所有CN PGXC_WLM_SESSION_INFO
operator_realtime级别 / operator级别 实时 当前CN GS_WLM_OPERATOR_STATISTICS
所有CN PGXC_WLM_OPERATOR_STATISTICS
历史 当前CN GS_WLM_OPERATOR_INFO
所有CN PGXC_WLM_OPERATOR_INFO


    GUC参数:

  • ENABLE_RESOURCE_TRACK (ON)

       是否开启监控功能,实时TopSQL的总开关,关闭之后实时TopSQL将不再进行记录,更不会在历史TopSQL中出现。

  • ENABLE_RESOURCE_RECORD(ON)

        设置是否开启资源监控记录归档功能。开启时,对于执行结束的记录,会分别被归档到相应的INFO视图,CNDN都需要设置上。

  • ENABLE_TRACK_RECORD_SUBSQL(ON)

        控制是否记录存储过程、匿名块内部语句(默认为on)(建议820及以上版本开启,TopSQL记录该子语句的前提是:子语句下推到DN执行;子语句执行时间超过resource_track_subsql_duration,目前TopSQL只能记录第一层循环的子语句,多层嵌套循环的子语句不会记录)。

  • RESOURCE_TRACK_DURATION(60s)

       设置实时TopSQL中记录的语句执行结束后进行历史信息转存的最小执行时间,该时间记录值的判断是包含了排队时间和运行时间,当排队时间+运行时间 > RESOURCE_TRACK_DURATION时,TopSQL历史视图会记录作业信息。

  • RESOURCE_TRACK_SUBSQL_DURATION(180s)

        存储过程内部语句转储的最小执行时间。

  • RESOURCE_TRACK_COST(0)

       设置对当前会话的语句进行资源监控的最小执行代价。

  • RESOURCE_TRACK_LEVEL(QUERY)

       设置当前会话的资源监控的等级,默认为query级别。

    • TOPSQL_RETENTION_TIME(30)

           历史TopSQLGS_WLM_SESSION_INFOGS_WLM_OPERATOR_INFO表中数据的保存时间,单位为天(历史TopSQL视图的数据实际是存储在postgres数据库中的dbms_om.gs_wlm_session_info系统表上,该表通过start_time进行分区,每天一个分区,通过参数topsql_retention_time配置默认保留30个分区即30天的记录,定期对pgxc_wlm_session_info的分区进行清理、创建,hash分布且分布键为queryid。如判断该表占用空间较多,可调低该参数,最多30min后表空间可下降)。

    • SESSION_HISTORY_MEMORY(100MB)

            设置历史查询视图的内存大小,如果语句运行过程中出现"TopSQL lfq is full, failed to save queryid"报错信息,可通过如下SQL查询TopSQL无锁队列总共的内存和已使用的内存。

    select * from pgxc_total_memory_detail where nodename like 'cn_%' and memorytype like '%topsql%' order by 1,2;

            如果发现某个CN节点topsql_used_memory大于或者即将大于max_topsql_memory,除调大该GUC参数外,可在该CN执行如下SQL,进行手动转储:

    CALL pg_catalog.create_wlm_session_info(1);

            通过GUC命令设置参数:

    gs_guc reload -Z coordinator -Z -N all -I all -c "enable_resource_track=on"
    gs_guc reload -Z coordinator -Z -N all -I all -c "resource_track_level=query"
    gs_guc reload -Z coordinator -Z -N all -I all -c "enable_resource_record=on"
    gs_guc reload -Z coordinator -Z -N all -I all -c "resource_track_duration=0"
    gs_guc reload -Z coordinator -Z -N all -I all -c "resource_track_cost=0"
    

    视图常用分析字段:

    字段名称 字段描述 分析出可能的现象
    block_time 语句执行前的阻塞时间,包含:语句解析、语句优化时间,以及作业排队时间。

    A1: block_time较大,而duration值并无明显变化,说明用户作业受其它作业影响,在真正开始执行前进行了较长时间的排队,下一步需要接着查看本数据表,统计起始时间小于start_time、结束时间大于finish_time的作业数量。

    A2: block_time较小,而duration值较大,说明用户作业执行时间增加较大原因是自己导致,需要继续分析数据量的变化情况、各DN的执行时间变化。

    start_time 语句开始执行时间戳。
    finish_time 语句执行结束时间戳。
    duration 语句执行时间长度。
    status 语句执行的结束状态,正常为finished,异常为aborted。 可以查看作业是否正常结束,如果异常,还会有异常原因。

    abort_info

    语句执行结束状态为aborted时显示异常信息。

    min_peak_memory

    语句在所有DN上的最小内存峰值,单位MB。

    B1: 对于同一个查询,可对比前后几次的内存消耗情况,内存消耗平均值能够反映出数据表的数据量是否有变化,memory_skew_percent值能够侧面反映出相关数据表在各DN上的数据分布是否有倾斜。

    并且,query_plan能够直接显示作业的执行计划,对比执行计划是否有变化。

    max_peak_memory

    语句在所有DN上的最大内存峰值,单位MB。

    average_peak_memory

    语句执行过程中的内存使用平均值,单位MB。

    memory_skew_percent

    语句各DN间的内存使用倾斜率。
    min_spill_size 若发生下盘,所有DN上下盘的最小数据量,单位MB。 C1: 对有大量下盘的查询有显著帮助信息,当下盘量剧增的时候,通常是表数据量有大幅增加,或者是执行计划有问题导致的,结合query_plan能进一步分析,spill_skew_percent可以查看作业是否有严重数据倾斜。

    max_spill_size

    若发生下盘,所有DN上下盘的最大数据量,单位MB。

    average_spill_siz

    若发生下盘,所有DN上下盘的平均数据量,单位MB。

    spill_skew_percent

    若发生下盘,DN间下盘倾斜率。

    min_dn_time

    语句在所有DN上的最小执行时间,单位ms。 D1: DN上的执行时间,结合duration数据,如果一个查询的DN执行时间有严重倾斜,那就需要考虑数据表的分区、分布列是否设置合适;不合理的分区、分布列,可能会导致本应分散到多个DN的执行任务被集中到个别DN上执行,执行时间必然大大增加。

    max_dn_time

    语句在所有DN上的最大执行时间,单位ms。
    average_dn_time

    语句在所有DN上的平均执行时间,单位ms。

    dntime_skew_percent

    语句在各DN间的执行时间倾斜率。

    min_cpu_time

    语句在所有DN上的最小CPU时间,单位ms。 E1: CPU执行时间是分配给改作业的实际执行时间,当duration有明显增加,而平均CPU执行时间无明显变化时,很可能的一个原因是作业执行期间,有多个其它计算密集型作业同时段执行,因CPU抢占的原因,拉长了该作业的执行时长。

    max_cpu_time

    语句在所有DN上的最大CPU时间,单位ms。

    total_cpu_time

    语句在所有DN上的CPU总时间,单位ms。

    cpu_skew_percent 语句在DN间的CPU时间倾斜率。

    min_peak_iops

    语句在所有DN上的每秒最小IO峰值。 F1: IO是变化最莫测的一个资源,一个作业在数据量不变、内存消耗无变化、CPU执行时间无变化、下盘量无变化的情况下,偏偏duration增加了,那最可能的原因是IO的原因。IO有点独特的是,往往IOPS变小反而反应了作业受其它作业影响,IO跑步起来,拖长了作业执行时间;其它属性通常相反,如:内存、CPU、下盘量,这些值变小通常意味着作业执行变快了。

    max_peak_iops

    语句在所有DN上的每秒最大IO峰值。

    average_peak_iops

    语句在所有DN上的每秒平均IO峰值。

    iops_skew_percent

    语句在DN间的IO倾斜率。
    query_plan 语句的执行计划。 G1: 作业执行计划是否有变化。
    unique_sql_id 标识一类语句 H1: 如果某类语句可能占用较多内存或者CPU资源,需要查杀,可利用gs_append_blocklist(unique_sql_id int8)或者gs_append_blocklist(sql_hash text)函数将该类语句加入黑名单,后续该类语句下发将不再执行。
    sql_hash

        总结:

    1. 因数据量变化,导致作业执行时间增加,可以分析A2/B1/D1/G1,进而确认作业查询的数据表是否有明显的数据量增加;

    2. 因其它并发作业抢占,导致作业排队,从而导致作业执行时间增加,可以分析A1/B1/D1,进而查看作业执行的同时期是否有大量并发作业在执行;

    3. 因其它作业而产生的CPU抢占,导致作业执行时间增加,可以分析A2/D1/E1,进而查看作业执行的同时期是否有大量并发作业在执行;

    4. 因其它作业而产生的IO抢占,导致作业执行时间增加,可以分析A2/F1,进而查看作业执行的同时期是否有大量并发作业在执行;

    5. 禁止某一类语句执行,可参考H1。

            值得注意的是,发生资源争抢时,可能会出现并发症,即CPU、IO抢占,作业排队现象都会发生,针对并发症问题,可以逐步分析解决,比如:第一步,调整作业执行顺序,减少并发作业数量,减少阻塞时间;第二步,定位出同时段执行的典型计算密集型、存储密集型作业,先移动到其它时间段执行,减少对本作业的影响;第三步,在无其他作业明显干预的情况下,做进一步分析,

        注意事项:

    • TopSQL不记录白名单和内部语句,但可正常记录超户下发的语句信息,可记录定时任务。
    • query和perf级别的topsql监控主要差异点在于query_plan字段,相比于query级别的算子信息,perf级别的query_plan字段增加算子的实际信息,如算子实际内存峰值,内存自动扩展信息,CU,Buffers等统计信息。
    • query和perf级别实时TopSQL和历史TopSQL的start_time字段信息含义不一致,实时TopSQL中的start_time表示的是作业下发的时间,历史TopSQL中的start_time表示的是作业真正开始运行的时间。
    • 查询历历史TopSQL Query,perf以及算子级别数据时,仅能通过postgres数据库进行访问。
    • 实时TopSQL中能够记录的SQL语句的规格是:
      1. 不记录特殊数据定义语句,如:SET、RESET、SHOW、ALTER SESSION SET、SET CONSTRAINTS语句;
      2. 记录数据定义语句,例如:执行CREATE、ALTER、DROP、GRANT、REVOKE和VACUUM语句;
      3. 记录数据操作语句,例如:
        • 执行SELECT、INSERT、UPDATE和DELETE语句。
        • 执行explain analyze和explain performance场景。
        • 使用query级别/perf级别视图。
      4. 记录函数与存储过程的调用入口语句,当GUC参数enable_track_record_subsql开启的情况下,可记录存储过程的部分内部语句(declare定义语句除外),仅会记录其中下发到DN执行的内部语句,未下发到DN执行的内部语句会被过滤掉;
      5. 记录匿名块语句,当GUC参数enable_track_record_subsql开启的情况下,可记录匿名块中的部分内部语句,仅会记录其中下发到DN执行的内部语句,未下发到DN执行的内部语句会被过滤掉;
      6. 记录游标语句,当游标并非从缓存中读取数据,而确实触发语句下发到DN上执行的条件下,该游标语句会被记录,并且会进行语句、执行计划增强,但当游标从缓存中读取数据时,不进行记录;当游标语句在匿名块或者函数中使用时,当游标从DN上读取较多数据但不完全使用时,因当前架构限制,无法记录该游标在DN上的监控信息。对于With Hold游标,该语法执行逻辑特殊,会在事务提交阶段执行实际查询动作,当语句在该阶段执行报错时,作业的aborted状态无法反馈到TopSQL历史表中。
      7. 重分布过程中的作业不统计;
      8. JDBC执行的带占位符语句,通常会补齐参数内容,但如果参数和原语句合起来长度超过64KB,则不记录参数,或者如果是轻量化语句,直接下发到DN上执行,不记录参数。
      9. 从8.1.3集群版本开始,query、perf级别TopSQL运行时监控功能已完全不影响查询性能,对当前会话的语句进行资源监控的GUC参数resource_track_cost默认值已修改为0,查询TopSQL实时监控视图时,默认会显示所有正在执行的语句。
      10. 从8.1.3集群版本开始,对于存储过程中的子语句监控功能,如果在查询TopSQL实时监控视图的会话中,开启控制子语句记录归档功能的GUC参数enable_track_record_subsql,不论业务语句中是否开启子语句监控开关,查询TopSQL实时监控视图的结果都能看到执行语句的子语句运行信息。
      11. 关于存储过程中子语句的监控功能即enable_track_record_subsql,8.1.3集群版本中建议不要全面开启,由于没有按时间过滤子语句的功能,全面开启可能会记录过多子语句,导致归档的监控表占用大量磁盘空间;8.1.3集群版本建议仅用于查询实时监控信息,或对个别存储过程业务做定位分析时,仅开启对应会话中的参数。8.2.1版本新增GUC参数resource_track_subsql_duration(默认值为180秒),可以通过执行时间过滤需要归档的子语句,用户可以按需调整该值大小。
      12. 由于规格限制,对于未下盘的主语句,TopSQL历史表中的记录会有延时,等待下次作业下发时才会显示在TopSQL历史表中。
      13. 从8.2.1.200集群版本开始,新增operator_realtime级别TopSQL运行时监控,提供算子级实时监控的能力,开启此级别的监控可以查询语句的执行计划以及具体执行信息,查询TopSQL算子级实时监控视图时,默认会显示所有正在执行的语句。但是对于存储过程和游标场景,暂时不支持显示算子级实时监控信息。另由于查询所有语句的信息对于CN内存压力较大,为了不影响作业性能,为用户提供查询单个语句的函数pg_stat_get_wlm_realtime_operator_info(queryid),可以通过该函数查询指定语句的算子执行信息。该版本暂时不支持算子历史信息查询。
      14. operator_realtime级别TopSQL运行时监控对于CN轻量化和存储过程的情况,暂时不支持。另由于算子执行速度较快的原因,对于算子信息的显示会有一定滞后性。
      15. query级别的作业监控和operator的算子监控中的spill_size字段,由于统计维度不同,会有一定差异,query级别监控监控的语句实际下盘文件大小,算子监控的是具体算子在逻辑层IO读写的数据量。
      16. 当GUC参数enable_stream_operator设置为off状态时,算子执行信息存在显示不准的情况。

    3、TopSQL原理介绍

            作业下发执行后,内核通过打桩记录作业的各项资源信息,如内存、CPU、下盘、IO和网络信息等,作业执行完成后该资源信息后先存在无锁队列中,资源管理后台辅助线程将该数据信息定期转储到dbms_om.gs_wlm_session_info系统表中,后续通过topsql_retention_time定期老化数据。



    4、通过TopSQL识别烂SQL

    • 识别stream数量多的语句
    select *,(length(query_plan) - length(replace(query_plan, 'Streaming', ''))) / length('Streaming') as stream_count FROM pgxc_wlm_session_info ORDER BY stream_count DESC limit 100;
    
    • 识别内存占用高的语句
    select * from pgxc_wlm_session_info where start_time > 'xxxx-xx-xx' and start_time < 'xxxx-xx-xx' order by max_peak_memory desc limit 100;
    
    • 识别需要优化的语句
    select * from pgxc_wlm_session_info where start_time > 'xxxx-xx-xx' and start_time < 'xxxx-xx-xx' and warning is not null order by duration desc limit 100;
    
    • 识别执行时间长的语句
    select * from pgxc_wlm_session_info where start_time > 'xxxx-xx-xx' and start_time < 'xxxx-xx-xx' order by duration desc;
    
    • 识别不下推的语句
    select * from pgxc_wlm_session_info where start_time > 'xxxx-xx-xx' and start_time < 'xxxx-xx-xx' and warning like ‘%can not be shipped%’ order by max_peak_memory desc;
    • 识别高CPU语句
    select * from pgxc_wlm_session_info where start_time > 'xxxx-xx-xx' and start_time < 'xxxx-xx-xx' order by max_cpu_time desc;
    
    • 识别下盘量大的语句
    select * from pgxc_wlm_session_info where start_time > 'xxxx-xx-xx' and start_time < 'xxxx-xx-xx' order by max_cpu_time desc;
    
    • 识别未做analyze的语句
    select * from pgxc_wlm_session_info where start_time > 'xxxx-xx-xx' and start_time < 'xxxx-xx-xx' and warning ilike '%statistics%';

    5、算子级TopSQL监控

        在SQL执行过程中,有些用户更希望能对算子执行进度进行监控,对于长时间运行的SQL,能够看出哪个算子执行时间长,通过算子执行时间和已处理行数等信息,确定是否需要查杀SQL,此时需要将RESOURCE_TRACK_LEVEL参数设置为OPERATOR。

        算子监控可以将SQL执行过程的算子监控数据以可视化的方式呈现出来,以便用户更加直观地了解算子的运行情况和性能表现。算子监控主要有以下价值:

    1. 提升用户体验:通过可视化的方式呈现算子执行信息,用户可以更加直观地了解算子的运行情况和性能。
    2. 性能优化:通过对算子监控数据的可视化分析,可以发现算子运行中的瓶颈和问题,从而及时进行优化和调整,提高算子的运行效率。
    3. 故障排查:通过对算子监控数据的可视化分析,可以及时发现算子运行中的问题和异常,从而及时进行修复和维护,提高SQL的可维护性。
    4. 提高算子的可扩展性:通过对算子监控数据的可视化分析,可以发现算子运行中的瓶颈和问题,从而及时进行优化和调整,提高算子的可扩展性,为后续的业务发展提供支持。

        OPERATOR算子监控和QUERY/PERF语句监控功能类似,均包含实时和历史二种形态,包含静态和动态二类信息:

    1. 语句静态信息是语句在真正执行前就已经由优化器生成的信息,如执行计划plan_node_namequeryid,预估行数estimated rows等信息。可用来分析生成的执行计划是否合适。
    2. 语句动态信息是语句在执行器中执行过程中所占用的资源信息,如算子执行进度progress、内存peak_memory、算子下盘spill_size、网络net_size、磁盘IO(read_byteswrite_bytes)CPUcpu_time)等不同DN的实时的信息记录。可用来分析语句执行过程中的进度和资源消耗情况,通过该字段可以分析出语句在运行是消耗较久的在什么地方,便于后续优化。

        功能展示:我们下发某个查询,在另一个会话中查询实时算子视图pgxc_wlm_operator_statistics,结果如下:

     

    6、TopSQL与其他视图交互

        不同视图从不同维度统计业务在数据库中的运行状态,因为或多或少都包含部分同类字段,可用于后续关联分析,此处给出历史TopSQL视图常交互的其他视图:

        使用示例:如果某个语句在历史TopSQL 历史pgxc_wlm_session_info视图中显示以往该作业很快就能正常运行完成,但是此时查杀pgxc_stat_activity发现该语句运行很长时间没有结束,如下图所示,则此时可能有异常,可利用以下步骤进行定位:

        常用定位过程如下所示:

        步骤1:查询pgxc_stat_activity活跃视图,找出长时间运行不结束的异常作业

    select coorname, usename, client_addr, now()-query_start as dur, state, enqueue, waiting, pid, query_id, substr(query,1,150) FROM pgxc_stat_activity WHERE usename not in ('omm','Ruby') and state = 'active' ORDER BY dur DESC limit 100;

        步骤2:根据步骤1得到的query信息,查询历史TopSQL视图,比较以往和现在的运行情况,如果以前运行时间很快,但当前语句运行时间很长未结束,则可考虑该语句已发生异常(历史topsql视图按天分区,查询时尽量带start_time条件)

     select * from pgxc_wlm_session_info where start_time > '2024-08-22 00:00' and start_time < '2024-08-24 00:00' and query ilike '%XXXXXXXXX%' order by start_time;

        步骤3:根据步骤1得到的query_id查询等待视图pgxc_thread_wait_status,得到作业线程号lwtid,并打出作业堆栈进行分析

    select * from pgxc_thread_wait_status where query_id = xxx;
    gstack xxx

    7、TopSQL实践

            某客户集群出现系统级性能问题,CPU持续飚高,业务受阻。

           通过TopSQL历史视图查询到有10+业务SQL存在stream数超过100,判断为CPU高的原因:

    postgres=# select *,(length(query_plan) - length(replace(query_plan, 'Streaming', ''))) / length('Streaming') as stream_count FROM pgxc_wlm_session_info ORDER BY stream_count DESC limit 100;

            针对此业务SQL进行下线并进行差分优化后,问题解决。

    8、参考文献

    1. GaussDB for DWS 负载管理核心技术解密二: 白话历史资源监视-云社区-华为云 (huaweicloud.com)
    2. GaussDB(DWS)监控工具指南(一)作业级监控TopSQL-云社区-华为云 (huaweicloud.com)
    3. GaussDB(DWS)监控工具指南(四)算子级监控【绽放吧!GaussDB(DWS)云原生数仓】-云社区-华为云 (huaweicloud.com)


    【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
    • 点赞
    • 收藏
    • 关注作者

    评论(0

    0/1000
    抱歉,系统识别当前为高风险访问,暂不支持该操作

    全部回复

    上滑加载中

    设置昵称

    在此一键设置昵称,即可参与社区互动!

    *长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

    *长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。