GaussDB(DWS) 监控工具指南【汇总版】
GaussDB(DWS)监控工具指南
1. 前言
- 适用版本:【8.1.3及以上】
监控系统是智能化管理和自动化运维的基石,事前及时语句发现故障,事后提供详实的数据用于追查定位问题,可以为资源规划,故障排查,性能优化提供至关重要的数据支持。本文主要对作业级监控TopSQL、用户级监控、资源池级监控和算子级监控进行详细介绍。
2. 作业级监控TopSQL
目前TopSQL功能被用户广泛使用,是性能定位、劣化分析、审计回溯等重要的基石,为用户提供覆盖内存、耗时、IO、网络、空间等多方面的监控能力。
本文以数仓813版本作为基线,对TopSQL进行介绍。
2.1 TopSQL功能介绍
对于用户而言,数据库是个黑盒,输入SQL语句,输出预期结果。在此过程中,用户关心两点:
- 输出结果是否符合预期;
- 语句要多久跑完。
关于第一个问题,用户需要关注下SQL语句写的是否合理。而对于第二个问题,普通用户可以通过explain等手段分析作业的执行计划,然而企业用户的SQL作业耗时久,影响较大,重跑代价较高,无法额外通过explain performance等手段进行分析,此时TopSQL可以帮助用户打开数据库黑盒,查看作业执行的实时情况和历史情况,便于用户分析数据库的情况。
TopSQL功能主要通过视图进行承载,如下表所示,本文以query级别的视图为例进行说明。
级别 | 类型 | 查询数据范围 | 视图名称 |
---|---|---|---|
query/perf级别 | |||
实时 | 单CN | GS_WLM_SESSION_STATISTICS | |
所有CN | PGXC_WLM_SESSION_STATISTICS | ||
历史 | 单CN | GS_WLM_SESSION_ INFO | |
所有CN | PGXC_WLM_SESSION_ INFO |
使用TopSQL功能需要sysadmin权限。此外,用户需先检查下TopSQL功能是否开启,涉及TopSQL的数据库GUC参数包括:
-
ENABLE_RESOURCE_TRACK (ON)
是否开启监控功能,实时TopSQL的总开关,关闭之后实时TopSQL将不再进行记录,更不会在历史TopSQL中出现。 -
RESOURCE_TRACK_COST(0)
设置对当前会话的语句进行资源监控的最小执行代价。 -
RESOURCE_TRACK_LEVEL(QUERY)
设置当前会话的资源监控的等级,默认为query级别。 -
RESOURCE_TRACK_DURATION(60S)
设置实时TopSQL中记录的语句执行结束后进行历史信息转存的最小执行时间,该时间记录值的判断是包含了排队时间和运行时间,当排队时间+运行时间 > RESOURCE_TRACK_DURATION时,TopSQL历史视图会记录作业信息。当执行完成的作业,其执行时间不小于此参数值时,作业信息会从实时视图(以STATISTICS为后缀的视图)转存到相应的历史视图 -
ENABLE_RESOURCE_RECORD(ON)
设置是否开启资源监控记录归档功能。开启时,对于执行结束的记录,会分别被归档到相应的INFO视图,CN和DN都需要设置上。 -
TOPSQL_RETENTION_TIME(30)
设置历史TopSQL中GS_WLM_SESSION_INFO和GS_WLM_OPERATOR_INFO表中数据的保存时间,单位为天
参数正确设置后,TopSQL会记录用户的SQL语句执行过程中的相关信息,用户可以使用TopSQL的视图筛选出执行时间较长的作业,专注于慢SQL的分析。
TopSQL功能分为实时TopSQL和历史TopSQL,以query级别为例,当需要查看正在运行的作业时,用户可查看实时TopSQL视图GS_WLM_SESSION_STATISTICS和PGXC_WLM_SESSION_STATISTICS,若需要对已经执行完成的作业进行分析,可查询历史TopSQL视图GS_WLM_SESSION_ HISTORY和PGXC_WLM_SESSION_ HISTORY。其中GS_开头的可以查询当前CN节点上正在执行的作业信息,PGXC_开头的可查询所有CN节点上正在执行的作业信息。
实时TopSQL视图为用户记录了作业运行时的相关信息,比如作业下发来源、阻塞时间、执行时长、开始时间、内存消耗、作业下盘量、作业IO、网络、语句类型、语句的执行计划等信息。用户可先通过resource_pool、nodename、username、query等信息定位到自己需要分析的语句,再通过作业运行信息定位问题。又或者用户可通过对查询进行筛选,筛选出当前占用资源较多的作业。
历史TopSQL视图记录了作业运行结束时的资源使用情况(包括内存、下盘、CPU时间等)和运行状态信息(包括报错、终止、异常等)以及性能告警信息。用户可通过对历史语句运行数据的分析,筛选出执行时长较大的语句,看语句执行计划是否有优化的空间,是否需要对表做一些analyze或者vacuum之类的操作。又比如对于内存报错的情况,可分析内存占用高的语句是否合理,从执行计划上分析是否有优化空间。
文末附TopSQL实践:常见问题现象及对应原因。
2.2 TopSQL的原理解析
2.2.1 TopSQL原理简介:
TopSQL的数据来源于数据库内核,当语句执行时,TopSQL会实时记录语句执行的相关信息。实时TopSQL数据会保存在内存的临时表中,当语句执行结束后,数据会转存到对应实体表GS_WLM_SESSION_INFO中,在实际使用中,由于下发作业繁多,历史TopSQL记录的作业数也不断增长,这样会导致INFO表中的数据量逐渐庞大,为了确保数仓整体性能不受影响,支持通过TOPSQL_RETENTION_TIME来设置INFO表中数据的保存时间(单位为天)。当数据存留时长超过这个时限,会对实体表GS_WLM_SESSION_INFO进行数据老化删除处理。
图 3-1 TopSQL数据流通图
如图3-1所示,各项GUC参数决定了TopSQL生成的记录信息,具体的参数说明详见第2节使用TopSQL前的检验。
2.2.2 性能分析:
对于企业用户而言,性能问题是Top级问题,对于TopSQL功能,我们进行了性能压测,在4TB的场景下,进行TPCC基准性能测试,进行了2000的并发压测,TPMC下降了约有2%,属于可接受的范围。
2.2.3 相关指标
语句属性列说明:
类型 | 描述 |
---|---|
username | 下发作业的用户 |
query_band | 用于标示作业类型,可通过GUC参数query_band进行设置,默认为空字符串,可通过该函数标识作业 |
queryid | 语句执行时标识语句的ID |
query | 正在执行的语句 |
resource_pool | 用户使用的资源池 |
enqueue | 作业负载管理状态 |
control_group | 作业所使用的cgroup |
query_plan | 作业的执行计划 |
warning | 作业的告警信息及SQL自诊断调优相关告警 |
stmt_type | 作业的类型,如INERT、UPDATE、DELETE等 |
语句的执行信息属性列,斜体代表可更换前缀/后缀式的指标,类似前缀后缀有(min_,max_,total_,average_,_skew_percent)
****指标 | 具体列名 | 描述 |
---|---|---|
语句执行时间 | block_time/start_time | 作业阻塞时长/作业开始运行时间 |
estimate_total_time/duration | 作业执行预估总时间/作业已经执行的时间(不包含作业排队的时间) | |
DN执行时长 | max_dn_time | 作业在所有DN上的执行时间(最小、最大、平均、倾斜率) |
max_cpu_time | 作业在所有DN上的运行占用CPU的时间(最小、最大、总和、倾斜率) | |
作业占用内存 | estimate_memory | 作业执行预估内存 |
max_peak_memory | 作业在所有DN上占用内存值峰值指标(最小、最大、平均、倾斜率) | |
下盘量 | spill_info | 作业在DN上的下盘信息.[a:b]:数量为b个DN中有a个DN下盘 |
max_spill_size | 作业在所有DN上的下盘数据量(最小、最大、平均、倾斜率) | |
读写IO | max_peak_iops | 作业在所有DN上的每秒IO峰值(最小、最大、平均、倾斜率) |
max_read_speed/max_write_speed | 作业在所有DN上的IO读速率/写速率(最小、最大、平均) | |
网络通信 | recv_pkg/send_pkg/recv_bytes/send_bytes | 各个DN上的网络收发包数量,收发数据量 |
2.2.4 特殊情况说明:
TopSQL由于自身限制,存在一些记录异常的情况,此处对8.1.3版本的TopSQL语句记录情况进行说明:
- 不记录特殊数据定义语句,如:SET、RESET、SHOW、ALTER SESSION SET、SET CONSTRAINTS语句;
- 记录数据定义语句,例如:执行CREATE、ALTER、DROP、GRANT、REVOKE和VACUUM语句;
- 记录数据操作语句,例如:
- 执行SELECT、INSERT、UPDATE和DELETE语句。
- 执行explain analyze和explain performance场景。
- 执行查询query级别/perf级别视图
- ODBC下发作业,由于多语句原因,会记录事务的BEGIN和end语句;
- JDBC下发作业,随机性多记录一条JDBC的内部语句
- 解析错误和语法报错的异常不记录
- 用户手动CANCEL作业,显示的监控数据可能为0;
- 当子语句开关打开后,只会记录下发到DN上执行的子语句;
- 游标语句,当游标并非从缓存中读取数据,而确实触发语句下发到DN上执行的条件下,该游标语句会被记录,并且会进行语句、执行计划增强,但当游标从缓存中读取数据时,不进行记录;当游标语句在匿名块或者函数中使用时,当游标从DN上读取较多数据但不完全使用时,无法记录该游标在DN上的监控信息。
- JDBC执行的带占位符语句,通常会补齐参数内容,但如果参数和原语句合起来长度超过64KB,则不记录参数,或者如果是轻量化语句,直接下发到DN上执行,不记录参数.
2.2.5 TopSQL漏记问题
TopSQL在813版本中有一些语句不会被记录,大体分为几种情况,特此说明:
- 用户提交的dbms_job.submit提交后定时运行的作业,TopSQL不会记录。
- 当系统开启GTM-Free模式时,即查询该GUC参数,结果为true时。如果下发作业的用户所属的资源池快车车道并发不进行管控,则topsql信息不记录。
show enable_gtm_free
比如查询:
select * from pg_resource_pool;
从上图可以看到default_pool资源池的active_statements和max_dop都为-1,都不进行管控,此时通过该资源池绑定的用户下发作业,TopSQL不记录作业信息。
2.3 TopSQL扩展及应用
TopSQL功能是GaussDB(DWS)支持性能问题定位、语句劣化分析、审计回溯等重要功能的基石。在此基础上,内核也拓展出了异常规则等一些高阶用法,在日常使用中,用户也对TopSQL提出了更高的要求,比如记录子语句、记录语句类型、提升算子级别语句监控准确性等诸多建议。为此,GaussDB(DWS)团队会在此基础上继续演进,更好的服务用户,提升用户满意度。
2.4 TopSQL实践:常见问题定位
</tr>
</tr>
字段名称 | 字段描述 | 分析出可能的现象 |
---|---|---|
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_size | 若发生下盘,所有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_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_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: 作业执行计划是否有变化。 |
enqueue | 语句的排队状态 | H1:作业是否异常排队/排队时间过久。可能出现的几种情况有:
1. Memory
|
warning | 语句的告警信息及SQL自诊断调优相关告警 | I1:可能出现的异常有下面几类以及SQL自诊断调优相关告警:
|
总结一下:
- 因数据量变化,导致作业执行时间增加,可以分析A2/B1/D1/G1,进而确认作业查询的数据表是否有明显的数据量增加;
- 因其它并发作业抢占,导致作业排队,从而导致作业执行时间增加,可以分析A1/B1/D1,进而查看作业执行的同时期是否有大量并发作业在执行;
- 因其它作业而产生的CPU抢占,导致作业执行时间增加,可以分析A2/D1/E1,进而查看作业执行的同时期是否有大量并发作业在执行;
- 因其它作业而产生的IO抢占,导致作业执行时间增加,可以分析A2/F1,进而查看作业执行的同时期是否有大量并发作业在执行;
- I1中有结果情况,可通过提示的信息进行分析,或者进行SQL自适应诊断相关告警处理,SQL自适应诊断处理方法见:https://support.huaweicloud.com/performance-dws/dws_10_0013.html
- 对于enqueue异常排队的情况H1,用户可参考:GaussDB(DWS)资源管理排队原理与问题定位-云社区-华为云 (huaweicloud.com),进行问题排查分析。
值得注意的是,发生资源争抢时,可能会出现并发症,即CPU、IO抢占,作业排队现象都会发生,针对并发症问题,可以逐步分析解决,比如:
第一步,调整作业执行顺序,减少并发作业数量,减少阻塞时间;
第二步,定位出同时段执行的典型计算密集型、存储密集型作业,先移动到其它时间段执行,减少对本作业的影响;
第三步,在无其他作业明显干预的情况下,做进一步分析,
3. 用户级监控
3.1 GuassDB(DWS)用户体系
对于一个产品来说,最简单的用户分类是普通用户、系统管理员、超级管理员三层体系。超级管理员拥有最高级的权限,普通用户作为最基本的用户,用户操作系统的部分权限,系统管理员也拥有部分权限,同时他也可改变普通用户的权限。超级管理员拥有所有权限,但是不轻易使用。
3.1.1 两层用户机制介绍
对于一个企业来说,对数据库的操作也是分部门运作,比如每个部门单独有的表,不同部分不能相互访问各自的表,但是公共部门的表又能跨部门访问,同时每个部门也有单独的数据库运行优先级等一些需求。
有鉴于此,GaussDB(DWS)设计的用户体系也分为两层:
第一层为组用户,该层用户关联组资源池,不作为执行作业的用户使用。
第二层为业务用户,该层用户关联业务资源池,可作为执行作业的用户使用。
组用户之间可使用的资源也可单独设置。每个业务用户之间亦可设置单独的资源。相较于以往单层的用户机制而言,两层的用户机制可实现对用户资源进行粒度更小的管控。
示例:
# 创建cgroup控制组
gs_ssh -c "gs_cgroup -c -S ClassG1 -G wn1"
# 创建组资源池resource_pool_a绑定ClassG1控制组。
CREATE RESOURCE POOL resource_pool_a WITH (control_group = 'ClassG1');
# 创建业务资源池resource_pool_a1绑定wn1控制组。
CREATE RESOURCE POOL resource_pool_a1 WITH (control_group = 'ClassG1:wn1');
# 创建组用户关联到组资源池。例如,名称为“tenant_a”的组用户关联到“resource_pool_a”组资源池
CREATE USER tenant_a RESOURCE POOL 'resource_pool_a' PASSWORD '********';
# 创建业务用户关联到业务资源池和组用户。例如,名称为“tenant_a1”的业务用户关联到“resource_pool_a1”组资源池和“tenant_a”组用户。
CREATE USER tenant_a1 RESOURCE POOL 'resource_pool_a1' USER GROUP 'tenant_a' PASSWORD '********';
3.1.2 用户权限
通常来说,对于单个部门的用户而言,自己的数据需要自己创建记录。此时,将用户关联到业务资源池后,进行创建表的操作即可,此时用户拥有自己创建表的增删改全部操作权限。然而,当用户需要访问其他部门的作业时,我们需要其他部门的管理员对该用户进行赋权操作。
当我们需要普通用户访问某个表时,可使用grant语法对用户赋权限或者收回权限,该操作需要拥有sysadmin权限的用户进行,举个例子,user_1是A部门员工,lineitem是B部门建的表,此时user_1需要跨部门访问lineitem表。此时可使用下面语句对user_1进行赋权操作。
# 将public表空间下的lineitem表的查询权限赋给user_1:
grant select on public.lineitem to user_1;
# 回收user_1的public表空间下的lineitem表的查询权限:
Revoke select on public.lineitem from user_1;
注:用户资源监控是基于用户操作来的,但是由于用户可访问非自己创建的表,所以,用户资源监控在数据统计时,表空间的增加会累计到表的创建者上,而用户对表操作时的语句执行信息,比如算子下盘量,临时空间占用等信息会累计到表的操作者身上。
3.2 用户资源监控
3.2.1 目标
一般情况下,数仓产品会同时有多个用户对数据库进行操作,每个用户使用的资源量有差异,举个极端的例子,当某个用户下发了慢SQL,导致集群整体性能劣化,此时我们就需要确定这个作业是哪个用户下发的,然后找到对应的慢SQL,对其进行管理。
对于管理员用户而言,用户监控可以帮助管理员以用户的维度了解系统的性能状况,及时发现并解决资源瓶颈和故障,提高系统的可靠性和稳定性。还可区分每个用户在整个集群中使用的资源量,确定哪些用户使用的资源量超标,然后对超标的用户进行限制。
3.2.2 监控维度
用户监控支持对CPU、内存、存储空间、临时空间、算子落盘空间、磁盘IO、网络等方面的监控,通过对这些资源的监控,管理员可以了解系统的负载情况、进程的运行状态、磁盘空间的使用情况、网络带宽的利用率等信息。这些信息可以帮助管理员及时发现系统的异常情况,及时采取措施,避免系统崩溃或者服务中断。
视图名 | 功能说明 |
---|---|
PG_TOTAL_USER_RESOURCE_INFO | 查询所有用户的资源限额和资源实时使用情况。 |
PGXC_TOTAL_USER_RESOURCE_INFO | 查询所有用户在全部节点的资源限额和资源实时使用情况。 |
GS_WLM_USER_RESOURCE_INFO(‘username’) | 查询具体某个用户的资源限额和资源实时使用情况 |
GS_WLM_USER_RESOURCE_HISTORY; | 查询所有用户在单节点的资源限额和资源历史使用情况 |
PGXC_WLM_USER_RESOURCE_HISTORY; | 查询所有用户在所有节点的资源限额和资源历史使用情况 |
使用示例:
postgres=# SELECT * FROM PG_TOTAL_USER_RESOURCE_INFO;
username | used_memory | total_memory | used_cpu | total_cpu | used_space | total_space | used_temp_space | total_temp_space | used_spill_space | total_spill_space | read_kbytes | write_kbytes | read_cou
nts | write_counts | read_speed | write_speed | send_speed | recv_speed
------------------+-------------+--------------+----------+-----------+------------+-------------+-----------------+------------------+------------------+-------------------+-------------+--------------+---------
----+--------------+------------+-------------+------------+------------
user_grp_1 | 0 | 4928 | 0 | 16 | 1573880 | -1 | 0 | -1 | 0 | -1 | 0 | 0 |
0 | 0 | 0 | 0 | 0 | 0
perfadm | 0 | 0 | 0 | 0 | 0 | -1 | 0 | -1 | 0 | -1 | 0 | 0 |
0 | 0 | 0 | 0 | 0 | 0
user_normal | 0 | 24643 | 0 | 16 | 0 | -1 | 0 | -1 | 0 | -1 | 0 | 0 |
0 | 0 | 0 | 0 | 0 | 0
usr1 | 0 | 69763 | 0 | 40 | 0 | -1 | 0 | -1 | 0 | -1 | 0 | 0 |
0 | 0 | 0 | 0 | 0 | 0
logical_cluster1 | 0 | 24643 | 0 | 16 | 1834424 | -1 | 0 | -1 | 0 | -1 | 0 | 0 |
0 | 0 | 0 | 0 | 0 | 0
user_2 | 0 | 985 | 0 | 16 | 0 | -1 | 0 | -1 | 0 | -1 | 0 | 0 |
0 | 0 | 0 | 0 | 0 | 0
user_1 | 0 | 3942 | 0 | 16 | 1573880 | -1 | 0 | -1 | 0 | -1 | 0 | 0 |
0 | 0 | 0 | 0 | 0 | 0
logical_cluster2 | 0 | 45120 | 0 | 24 | 0 | -1 | 0 | -1 | 0 | -1 | 0 | 0 |
0 | 0 | 0 | 0 | 0 | 0
user_default | 0 | 24643 | 0 | 16 | 0 | -1 | 0 | -1 | 0 | -1 | 0 | 0 |
0 | 0 | 0 | 0 | 0 | 0
wjx | 0 | 24643 | 0 | 16 | 0 | -1 | 0 | -1 | 0 | -1 | 0 | 0 |
0 | 0 | 0 | 0 | 0 | 0
(10 rows)
postgres=# select * from GS_WLM_USER_RESOURCE_HISTORY;
username | timestamp | used_memory | total_memory | used_cpu | total_cpu | used_space | total_space | used_temp_space | total_temp_space | used_spill_space | total_spill_space | read_
kbytes | write_kbytes | read_counts | write_counts | read_speed | write_speed | send_speed | recv_speed
------------------+-------------------------------+-------------+--------------+----------+-----------+------------+-------------+-----------------+------------------+------------------+-------------------+------
-------+--------------+-------------+--------------+------------+-------------+------------+------------
user_grp_1 | 2023-05-22 16:51:03.380482+08 | 0 | 4928 | 0 | 16 | 1573880 | -1 | 0 | -1 | 0 | -1 |
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0
wjx | 2023-05-22 16:51:03.380482+08 | 0 | 24643 | 0 | 16 | 0 | -1 | 0 | -1 | 0 | -1 |
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0
user_default | 2023-05-22 16:51:03.380482+08 | 0 | 24643 | 0 | 16 | 0 | -1 | 0 | -1 | 0 | -1 |
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0
logical_cluster2 | 2023-05-22 16:51:03.380482+08 | 0 | 45120 | 0 | 24 | 0 | -1 | 0 | -1 | 0 | -1 |
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0
user_1 | 2023-05-22 16:51:03.380482+08 | 0 | 3942 | 0 | 16 | 1573880 | -1 | 0 | -1 | 0 | -1 |
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0
user_2 | 2023-05-22 16:51:03.380482+08 | 0 | 985 | 0 | 16 | 0 | -1 | 0 | -1 | 0 | -1 |
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0
logical_cluster1 | 2023-05-22 16:51:03.380482+08 | 0 | 24643 | 0 | 16 | 1834424 | -1 | 0 | -1 | 0 | -1 |
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0
usr1 | 2023-05-22 16:51:03.380482+08 | 0 | 69763 | 0 | 40 | 0 | -1 | 0 | -1 | 0 | -1 |
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0
user_normal | 2023-05-22 16:51:03.380482+08 | 0 | 24643 | 0 | 16 | 0 | -1 | 0 | -1 | 0 | -1 |
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0
3.2.3 监控原理
内核在作业运行时,依据作业携带的用户信息,进行相关资源字段的累计,每隔一段时间将信息汇总至用户监控历史表中。此外,该功能的使用有些规格
3.2.3.1 相关GUC参数
enable_logical_io_statistics:用户资源监控和资源池资源监控IO相关数值的开关,默认为on,开启后用户监控中io相关记录(read_kbytes、write_kbytes、read_counts、write_counts、read_speed和write_speed)会进行统计。
enable_user_metric_persistent:否开启用户/资源池历史资源监控转存功能,开启后会将监控记录转存到历史表中。
user_metric_retention_time:设置用户历史资源监控数据的保存天数,默认为7天
3.2.3.2 相关说明
当前用户监控可同时监控快慢车道的所有作业的CPU、IO和内存使用情况。
当用户在CN上进行查询时,显示的为所有DN资源池使用和资源限制的累积和。在DN查询时仅统计本DN上资源池使用和资源限制信息。
DN上数据收集周期为5s,CN每隔5s从DN上收集一次信息。辅助线程每30s自动进行持久化操作,持久化用户监控数据。
对于初始管理用户暂不进行资源监控,因为该用户是超级管理员用户,没必要监控。
3.2.4 案例分析
2.4.1 当出现内存不可用时,可通过该视图查看是哪个用户使用的内存过高
2.4.2 可以监控用户网络使用情况,比如网络的收发速率等。
4. 资源池级监控
4.1 资源池
在数据库最初阶段,是没有资源概念的,给数据库输入SQL语句,数据库输出结果,在简单业务场景下,用户独占数据库是不存在资源争抢问题的。随着数据库业务增长,用户也越来越多,此时不同用户间的SQL会抢占操作系统的资源(CPU、内存、IO、网络等),如果不加限制的话就会影响整个集群的用户,造成集群不可用的情况。为了防止在这种场景发生,需要对用户业务SQL进行区分,对不同的用户需要资源分配和管控。为此,资源池应运而生,资源池作为一种逻辑媒介,连接用户和系统资源,管控每个用户的资源使用,保证集群的可用状态。
4.2 GaussDB(DWS)中的资源池
当管理员创建用户后,会自动绑定在默认资源池default_pool上,从网页上,可以再创建资源池,然后绑定相应的用户在对应的资源池上。此时用户下发SQL语句执行,下发的语句就会收到资源池配置参数的管控。通过资源池可以划分不同用户的资源使用情况,简化了集群的管理,它可以统一管理所有的系统计算资源。这意味着管理员只需要管理资源池,而不是每个节点上的资源。
GaussDB(DWS)资源池(租户)功能支持通过管控CPU、并发、内存、网络等手段对用户下发的业务语句进行管控,在不同的维度对用户语句进行管控。具体来说支持设置资源池参数的方式控制并发、内存、CPU利用率等能力。当用户的语句是未知新语句时,也可以通过一些异常规则来控制语句情况,比如查杀超过限制的烂SQL等,在此基础上,还支持设置黑名单的方式严格管控用户下发的语句,这些功能后续会进行说明,本文聚焦资源池先不展开。
通过下列语句可查询资源池信息
postgres=# select * from pg_resource_pool;
respool_name | mem_percent | cpu_affinity | control_group | active_statements | max_dop | memory_limit | parentid | io_limits | io_priority | nodegroup | is_foreign | short_acc | except_rule | weight
----------------------+-------------+--------------+---------------------+-------------------+---------+--------------+------------+-----------+-------------+------------------+------------+-----------+-------------+--------
default_pool | 0 | -1 | DefaultClass:Medium | -1 | -1 | default | 0 | 0 | None | installation | f | t | None | -1
respool_1 | 0 | -1 | ClassN1:wn1 | 10 | -1 | default | 0 | 0 | None | logical_cluster1 | f | t | None | -1
respool_grp_1 | 20 | -1 | ClassG1 | 10 | -1 | default | 0 | 0 | None | logical_cluster1 | f | t | None | -1
respool_g1_job_1 | 20 | -1 | ClassG1:wg1_1 | 10 | -1 | default | 2147484586 | 0 | None | logical_cluster1 | f | t | None | -1
respool_g1_job_2 | 20 | -1 | ClassG1:wg1_2 | 10 | -1 | default | 2147484586 | 0 | None | logical_cluster1 | f | t | None | -1
respool_0_mempercent | 0 | -1 | DefaultClass:Medium | 10 | -1 | default | 0 | 0 | None | logical_cluster1 | f | t | None | -1
(6 rows)
对于资源池的相关参数,用户可通过管控面进行配置,同时也支持管理员通过语句来修改资源池配置,如下所示,可修改默认资源池的快车道并发限制。其他参数同理,不过该操作有风险,建议用户在GaussDB(DWS)运维人员确认后执行。
alter resource pool default_pool with (max_dop=1);
4.3 资源池监控
GaussDB(DWS)为用户提供了多维度的资源监控视图,可支持从不同维度查询集群状态。
GaussDB(DWS)提供资源池级别的监控能力,监控SQL语句的运行情况,主要包含实时监控和历史监控,跟用户监控类似,资源池监控展示了每个资源池的运行作业数、排队作业数、内存使用、内存使用上限、 CPU使用情况、读写IO情况等,通过下列语句可进行查询获取
postgres=# select * from gs_respool_resource_info;
nodegroup | rpname | cgroup | ref_count | fast_run | fast_wait | fast_limit | slow_run | slow_wait | slow_limit | used_cpu | cpu_limit | used_mem | estimate_mem | mem_limit | read_kbytes | write_kbytes | read_counts | write_counts | read_speed | write_speed
-----------+--------------+---------------------+-----------+----------+-----------+------------+----------+-----------+------------+----------+-----------+----------+--------------+-----------+-------------+--------------+-------------+--------------+------------+-------------
lc1 | pool_group | ClassN | 0 | 0 | 0 | -1 | 0 | 0 | 10 | 0 | 312 | 0 | 0 | 116844 | 0 | 0 | 0 | 0 | 0 | 0
lc1 | pool_work | ClassN:wg1 | 0 | 0 | 0 | 10 | 0 | 0 | 10 | 0 | 312 | 0 | 0 | 23364 | 0 | 0 | 0 | 0 | 0 | 0
lc2 | default_pool | DefaultClass:Medium | 0 | 0 | 0 | -1 | 0 | 0 | -1 | 0 | 208 | 0 | 0 | 584220 | 0 | 0 | 0 | 0 | 0 | 0
lc1 | resp_other | DefaultClass:Medium | 0 | 0 | 0 | -1 | 0 | 0 | 100 | 0 | 312 | 0 | 0 | 175260 | 0 | 0 | 0 | 0 | 0 | 0
lc1 | default_pool | DefaultClass:Medium | 0 | 0 | 0 | -1 | 0 | 0 | -1 | 0 | 312 | 0 | 0 | 584220 | 0 | 0 | 0 | 0 | 0 | 0
(5 rows)
其中,nodegroup 代表资源池所属的逻辑集群信息。fast_run、slow_run代表资源池快车道运行数、慢车道运行数,fast_wait、slow_wait为快车道和慢车道的排队作业数。其中,slow_wait也包含了CCN排队的作业。fast_limit和slow_limit代表了快慢车道的并发上限,cpu_limit代表了资源池配置的cpu设置的限额是多少,通过used_cpu可以看到不同资源池的CPU使用率情况。estimate_mem为资源池内用户下发作业的估算内存总和,used_mem为资源池实际使用的内存,mem_limit为资源池设置的可用内存上限。
同样,历史资源监控也提供了历史问题定位的能力,该视图会30s采集一次,timestamp为采集的时刻。
postgres=# select * from gs_respool_resource_history;
timestamp | nodegroup | rpname | cgroup | ref_count | fast_run | fast_wait | fast_limit | slow_run | slow_wait | slow_limit | used_cpu | cpu_limit | used_mem | estimate_mem | mem_limit | read_kbytes | write_kbytes | read_counts | write_counts | read_speed | write_speed
-------------------------------+-----------+--------------+---------------------+-----------+----------+-----------+------------+----------+-----------+------------+----------+-----------+----------+--------------+-----------+-------------+--------------+-------------+--------------+------------+-------------
2023-10-20 20:24:14.715107+08 | lc1 | pool_group | ClassN | 0 | 0 | 0 | -1 | 0 | 0 | 10 | 0 | 312 | 0 | 0 | 116844 | 0 | 0 | 0 | 0 | 0 | 0
2023-10-20 20:24:14.715107+08 | lc1 | pool_work | ClassN:wg1 | 0 | 0 | 0 | 10 | 0 | 0 | 10 | 0 | 312 | 0 | 0 | 23364 | 0 | 0 | 0 | 0 | 0 | 0
2023-10-20 20:24:14.715107+08 | lc2 | default_pool | DefaultClass:Medium | 0 | 0 | 0 | -1 | 0 | 0 | -1 | 0 | 208 | 0 | 0 | 584220 | 0 | 0 | 0 | 0 | 0 | 0
2023-10-20 20:24:14.715107+08 | lc1 | resp_other | DefaultClass:Medium | 0 | 0 | 0 | -1 | 0 | 0 | 100 | 0 | 312 | 0 | 0 | 175260 | 0 | 0 | 0 | 0 | 0 | 0
2023-10-20 20:24:14.715107+08 | lc1 | default_pool | DefaultClass:Medium | 0 | 0 | 0 | -1 | 0 | 0 | -1 | 0 | 312 | 0 | 0 | 584220 | 0 | 0 | 0 | 0 | 0 | 0
2023-10-20 20:24:44.791512+08 | lc1 | pool_group | ClassN | 0 | 0 | 0 | -1 | 0 | 0 | 10 | 0 | 312 | 0 | 0 | 116844 | 0 | 0 | 0 | 0 | 0 | 0
2023-10-20 20:24:44.791512+08 | lc1 | pool_work | ClassN:wg1 | 0 | 0 | 0 | 10 | 0 | 0 | 10 | 0 | 312 | 0 | 0 | 23364 | 0 | 0 | 0 | 0 | 0 | 0
2023-10-20 20:24:44.791512+08 | lc2 | default_pool | DefaultClass:Medium | 0 | 0 | 0 | -1 | 0 | 0 | -1 | 0 | 208 | 0 | 0 | 584220 | 0 | 0 | 0 | 0 | 0 | 0
2023-10-20 20:24:44.791512+08 | lc1 | resp_other | DefaultClass:Medium | 0 | 0 | 0 | -1 | 0 | 0 | 100 | 0 | 312 | 0 | 0 | 175260 | 0 | 0 | 0 | 0 | 0 | 0
2023-10-20 20:24:44.791512+08 | lc1 | default_pool | DefaultClass:Medium | 0 | 0 | 0 | -1 | 0 | 0 | -1 | 0 | 312 | 0 | 0 | 584220 | 0 | 0 | 0 | 0 | 0 | 0
...
4.4 GaussDB(DWS)中的资源池
-
当发现业务反馈语句阻塞严重,不执行作业,可查询实时资源池监控或者历史资源池监控进行分析,看是否作业堆积排队,如果fast_limit上的限制为10,,fast_run字段也为10,然后fast_wait较多,此时可尝试修改资源池参数max_dop,适当调大并发上限。
-
业务反馈跑批业务在正常运行的情况下批量变慢,此时可观察历史资源池监控对比观察,统计劣化前后同一批作业一段时间的内存资源使用情况,也可通过当时资源池作业排队现象来定位问题。
4.5 GaussDB(DWS)中的资源池
为了提升系统可用性,GaussDB(DWS)也提供了更便捷,更易用的视图用以帮用户进行观察系统状态和定位问题。
在内核821版本中,用户可使用gs_query_monitor、gs_user_monitor、gs_respool_monitor视图进行语句级、用户级、资源池的资源监控,这些视图以GaussDB(DWS)监控工具指南系列中所讲的视图为基础,选取常用的定位字段,为现网用户提供更易用的一套实时监控脚本。
具体效果如下:
- 作业监控
postgres=# select * from gs_query_monitor;
usename | nodename | nodegroup | rpname | priority | xact_start | query_start | block_time | duration | query_band | attribute | lane | status | queue | used_mem | estimate_mem | used_cpu | read_speed | write_speed | send_speed | recv_speed | dn_count | stream_count | pid | lw
tid | query_id | unique_sql_id | query
--------------+----------+------------------+--------------+----------+-------------------------------+-------------------------------+------------+----------+------------+-------------+------+---------+-------+----------+--------------+----------+------------+-------------+------------+------------+----------+--------------+-----------------+---
-----+-------------------+---------------+--------------------------------------------------
user_default | cn_5001 | logical_cluster1 | default_pool | Medium | 2023-10-30 16:39:28.754207+08 | 2023-10-30 16:39:28.748855+08 | 59 | 0 | | Complicated | slow | pending | CCN | 0 | 4360 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 139906878865264 | 98
2280 | 72902018968076864 | 2372000271 | INSERT INTO t1 SELECT generate_series(1,100000);
user_default | cn_5001 | logical_cluster1 | default_pool | Medium | 2023-10-30 16:39:28.760305+08 | 2023-10-30 16:39:28.754861+08 | 59 | 0 | | Complicated | slow | pending | CCN | 0 | 4360 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 139906878866632 | 98
2283 | 72902018968076871 | 2372000271 | INSERT INTO t1 SELECT generate_series(1,100000);
user_default | cn_5001 | logical_cluster1 | default_pool | Medium | 2023-10-30 16:39:28.761491+08 | 2023-10-30 16:39:28.756124+08 | 59 | 0 | | Complicated | slow | pending | CCN | 0 | 4360 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 139906878865720 | 98
2281 | 72902018968076872 | 2372000271 | INSERT INTO t1 SELECT generate_series(1,100000);
user_default | cn_5001 | logical_cluster1 | default_pool | Medium | 2023-10-30 16:39:28.768333+08 | 2023-10-30 16:39:28.762653+08 | 59 | 0 | | Complicated | slow | pending | CCN | 0 | 4360 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 139906878867544 | 98
2285 | 72902018968076877 | 2372000271 | INSERT INTO t1 SELECT generate_series(1,100000);
user_default | cn_5001 | logical_cluster1 | default_pool | Medium | 2023-10-30 16:39:28.772288+08 | 2023-10-30 16:39:28.766933+08 | 59 | 0 | | Complicated | slow | pending | CCN | 0 | 4360 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 139906878868912 | 98
2288 | 72902018968076881 | 2372000271 | INSERT INTO t1 SELECT generate_series(1,100000);
user_default | cn_5001 | logical_cluster1 | default_pool | Medium | 2023-10-30 16:39:28.772304+08 | 2023-10-30 16:39:28.766966+08 | 59 | 0 | | Complicated | slow | pending | CCN | 0 | 4360 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 139906878867088 | 98
2284 | 72902018968076882 | 2372000271 | INSERT INTO t1 SELECT generate_series(1,100000);
user_default | cn_5001 | logical_cluster1 | default_pool | Medium | 2023-10-30 16:39:28.777958+08 | 2023-10-30 16:39:28.772572+08 | 59 | 0 | | Complicated | slow | pending | CCN | 0 | 4360 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 139906878868000 | 98
2286 | 72902018968076888 | 2372000271 | INSERT INTO t1 SELECT generate_series(1,100000);
user_default | cn_5001 | logical_cluster1 | default_pool | Medium | 2023-10-30 16:39:28.779373+08 | 2023-10-30 16:39:28.773997+08 | 59 | 0 | | Complicated | slow | pending | CCN | 0 | 4360 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 139906878868456 | 98
2287 | 72902018968076889 | 2372000271 | INSERT INTO t1 SELECT generate_series(1,100000);
user_default | cn_5001 | logical_cluster1 | default_pool | Medium | 2023-10-30 16:39:28.753845+08 | 2023-10-30 16:39:28.748498+08 | 0 | 59 | | Complicated | slow | running | None | 4 | 4360 | .289 | 0 | 0 | 0 | 0 | 0 | 0 | 139906878864808 | 98
2279 | 72902018968076862 | 2372000271 | INSERT INTO t1 SELECT generate_series(1,100000);
user_default | cn_5001 | logical_cluster1 | default_pool | Medium | 2023-10-30 16:39:28.753957+08 | 2023-10-30 16:39:28.748609+08 | 0 | 59 | | Complicated | slow | running | None | 4 | 4360 | .288 | 0 | 0 | 17 | 23 | 0 | 0 | 139906878866176 | 98
2282 | 72902018968076863 | 2372000271 | INSERT INTO t1 SELECT generate_series(1,100000);
(10 rows)
- 用户监控
postgres=# select * from gs_user_monitor;
usename | rpname | nodegroup | session_count | active_count | global_wait | fast_run | fast_wait | slow_run | slow_wait | used_mem | estimate_mem | used_cpu | read_speed | write_speed | send_speed | recv_speed | used_space | space_limit | used_temp_space | temp_space_limit | used_spill_space | spill_space_limit
------------------+---------------+------------------+---------------+--------------+-------------+----------+-----------+----------+-----------+----------+--------------+----------+------------+-------------+------------+------------+------------+-------------+-----------------+------------------+------------------+-------------------
logical_cluster2 | default_pool | logical_cluster2 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -1 | 0 | -1 | 0 | -1
user_grp_1 | respool_grp_1 | logical_cluster1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -1 | 0 | -1 | 0 | -1
logical_cluster1 | default_pool | logical_cluster1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1834424 | -1 | 0 | -1 | 0 | -1
user_normal | respool_1 | logical_cluster1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -1 | 0 | -1 | 0 | -1
user_default | default_pool | logical_cluster1 | 10 | 10 | 0 | 0 | 0 | 2 | 8 | 8 | 8720 | .563 | 0 | 15 | 0 | 0 | 640080 | -1 | 0 | -1 | 0 | -1
(5 rows)
- 资源池监控
postgres=# select * from gs_respool_monitor;
rpname | nodegroup | cn_count | short_acc | session_count | active_count | global_wait | fast_run | fast_wait | fast_limit | slow_run | slow_wait | slow_limit | used_mem | estimate_mem | mem_limit | query_mem_limit | used_cpu | cpu_limit | read_speed | write_speed | send_speed | recv_speed
----------------------+------------------+----------+-----------+---------------+--------------+-------------+----------+-----------+------------+----------+-----------+------------+----------+--------------+-----------+-----------------+----------+-----------+------------+-------------+------------+------------
default_pool | logical_cluster2 | 3 | t | 0 | 0 | 0 | 0 | 0 | -1 | 0 | 0 | -1 | 0 bytes | 0 bytes | 11 GB | 4376 MB | 0 | 8 | 0 bytes/s | 0 bytes/s | 0 bytes/s | 0 bytes/s
respool_g1_job_1 | logical_cluster1 | 3 | t | 0 | 0 | 0 | 0 | 0 | -1 | 0 | 0 | 10 | 0 bytes | 0 bytes | 437 MB | 175 MB | 0 | 8 | 0 bytes/s | 0 bytes/s | 0 bytes/s | 0 bytes/s
respool_1 | logical_cluster1 | 3 | t | 0 | 0 | 0 | 0 | 0 | -1 | 0 | 0 | 10 | 0 bytes | 0 bytes | 11 GB | 4376 MB | 0 | 8 | 0 bytes/s | 0 bytes/s | 0 bytes/s | 0 bytes/s
respool_0_mempercent | logical_cluster1 | 3 | t | 0 | 0 | 0 | 0 | 0 | -1 | 0 | 0 | 10 | 0 bytes | 0 bytes | 11 GB | 4376 MB | 0 | 8 | 0 bytes/s | 0 bytes/s | 0 bytes/s | 0 bytes/s
respool_g1_job_2 | logical_cluster1 | 3 | t | 0 | 0 | 0 | 0 | 0 | -1 | 0 | 0 | 10 | 0 bytes | 0 bytes | 437 MB | 175 MB | 0 | 8 | 0 bytes/s | 0 bytes/s | 0 bytes/s | 0 bytes/s
default_pool | logical_cluster1 | 3 | t | 10 | 10 | 0 | 0 | 0 | -1 | 2 | 8 | -1 | 8192 KB | 8720 MB | 11 GB | 4376 MB | .577 | 8 | 0 bytes/s | 17 KB/s | 0 bytes/s | 0 bytes/s
(6 rows)
5. 算子级监控
随着数据量的增大和数据处理的复杂性增加,数据库系统的性能问题变得越来越突出。应用程序对数据库的访问频率和数据量也越来越大。因此,优化数据库系统的性能成为了数据库管理员和开发人员的重要任务。通过SQL性能调优,可以提高数据库系统的响应速度和吞吐量,减少资源消耗,提高系统的稳定性和可靠性,从而提高应用程序的性能和用户体验。目前GaussDB(DWS)已有的explain工具无法满足用户实时定位问题的需求,为此DWS推出了算子级监控,以解决实时算子难以观测的问题。
5.1 需求描述
个例子,用户下发语句后,无法知道当前语句的执行计划生成的是否合理,目前语句的执行进度和消耗资源等情况。如下图所示,用户仅能看到执行花费了多长时间,并不能看到语句后面执行的什么信息?算子是咋样运行的?每个算子怎么交互的,生成的计划是否合理,无法进行判断。
为此,DWS提供了explain performance的方式进行事后分析,而explain performance需要将语句执行完后才能看到结果,对于某些新上业务的语句,不知道会运行多久,甚至说能不能运行出来结果都不知道,所以无法直接通过explain performance分析结果。
因此亟需一种实时观测语句算子运行的手段来确定执行计划的优化点,以便SQL调优。
5.2 解决方案
针对这些情况,GaussDB(DWS)在新版本821新推出了算子监控,算子监控能看到语句具体运行的情况,能追踪到具体某个算子的进度以及消耗资源情况。使用步骤如下:
1)设置guc参数resource_track_level为operator_realtime级别,然后执行语句;
2)重新打开一个窗口,连接gaussdb,通过pgxc_wlm_operator_statistics查询集群所有打开算子监控的语句,又或者通过查询pg_stat_get_wlm_realtime_operator_info(queryid)可以获取到该queryid对应语句的信息。
select * from pgxc_wlm_operator_statistics;
注:该功能对性能有一定影响,执行基线测试,同样情况下可能会最大新增2%左右的性能劣化,建议用户在追踪性能问题时使用。
算子监控跟语句监控功能类似,同样包含的语句的静态信息和运行态信息。
1)语句静态信息是语句在真正执行前就已经由优化器生成的信息,如执行计划plan_node_name,queryid,预估行数estimated rows等信息。可用来分析生成的执行计划是否合适。
2)语句动态信息是语句在执行器中执行过程中所占用的资源信息,如算子执行进度progress、内存peak_memory、算子下盘spill_size、网络net_size、磁盘IO(read_bytes、write_bytes),CPU(cpu_time)等不同DN的实时的信息记录。可用来分析语句执行过程中的进度和资源消耗情况,通过该字段可以分析出语句在运行是消耗较久的在什么地方,便于后续优化。
5.3 实际使用
我们下发某个查询,在另一个会话中查询算子视图,结果如下:
1)当前算子进度:字段progress展示了当前算子的运行进度,对于第一个算子而言,该字段展示的是当前语句的整体进度。
2)不断刷新视图,能看到语句执行情况,观察进度介于(0,100)之间的进度算子,这些代表该算子正在运行。
3)观察当前算子实际消耗资源情况,判断可能阻塞的原因。
6. 总结
- 作业级监控(TopSQL)主要是对运行作业的监控,包括了实时运行作业的相关信息,历史运行作业的相关信息等。它收集的数据来源于数据库内部,为用户提供了实时监控数据库的能力。
- 用户监控支持对CPU、内存、存储空间、临时空间、算子落盘空间、磁盘IO、网络等方面的监控。
- GaussDB(DWS)提供资源池级别的监控能力,监控SQL语句的运行情况,主要包含实时监控和历史监控,跟用户监控类似,资源池监控展示了每个资源池的运行作业数、排队作业数、内存使用、内存使用上限、 CPU使用情况、读写IO情况
- 以往需要explain performance执行完毕后才能获取算子运行信息,现在通过该视图可以直接在运行期间获取,且该视图对结果集无影响。本文提供的视图可以支持用户对语句算子进行实时监控,能较为准确的反应语句的执行情况,通过观察运行时长较久的算子和消耗资源,可以判断计划生成是否合理,又或者通过进度字段观察语句运行进度可用来定位SQL性能问题。当然,该视图也许和其他运行态的视图结合使用,最终确定SQL性能较慢的原因,并采取措施进行调优。
7. 参考文档
- 点赞
- 收藏
- 关注作者
评论(0)