GaussDB for DWS Hang问题定位指南

举报
carl@1234 发表于 2020/06/11 16:24:35 2020/06/11
【摘要】 1 Hang问题基础知识GaussDB 200为分布式数据库,通常由于单节点亚健康、系统资源紧张或查询本身的计划等问题,造成系统疑似发生Hang。Hang问题的产生原因由很多种,比如,死锁等待、日志同步等待、事务超时、通信故障、数据溢出发生死循环等等,更为常见的是由于执行慢、中间结果集倾斜而导致的疑似Hang。掌握Hang问题的基本定位方法对于大集群环境下快速找准疑似阻塞点,修复故障环境或优...

Hang问题基础知识

GaussDB for DWS 为分布式数据库,通常由于单节点亚健康系统资源紧张查询本身的计划问题,造成系统疑似发生HangHang问题的产生原因由很多种,比如死锁等待日志同步等待、事务超时、通信故障、数据溢出发生死循环等等,更为常见的由于执行慢、中间结果集倾斜而导致的疑似Hang。掌握Hang问题的基本定位方法对于大集群环境下快速找准疑似阻塞点,修复故障环境或优化执行性能是至关重要的

1.1 常用视图

目前GaussDB for DWS对外提供诸多系统视图,可以用来辅助Hang问题的分析定位

常用视图用法说明如下表所示。代表常用程度

 

pgxc_stat_activity ☆☆

查询当前集群所有DN实例上各个session信息,重点关注正在执行(state状态为active)SQL我们一般首先分析pgxc_stat_activity中的内容,初步根据执行时间筛选出疑似query,然后使用queryquery_id视图pgxc_thread_wait_status结合,获取query集群级别的线程状态进行hang问题分析

 

视图需要以超级用户的身份来运行

 

问题分析时,我们首先需要客户反馈的疑似hang的作业信息,根据作业所在databse、运行作业的用户身份、运行作业客户端以及运行作业所连接实例CN名称初步筛选出问题SQL的运行信息,具体运行信息见附件中字段含义解释。比如疑似hang作业是以omm用户运行postgres数据库连接到cn_5001实例上运行的,我们使用如下SQL进行作业状态查询


 


我们可以根据上述返回的结果,结合作业运行的客户端名称、客户端ip作业query运行开始时间query_start进一步筛选出疑似hang作业

 

【附视图各字段含义

字段名称数据类型字段描述coornametext运行业务SQL的CN节点名称datidoid用户会话在后台连接到的数据库OID。datnamename用户会话在后台连接到的数据库名称。可以看到此语句实际在哪个数据库运行,来帮助区分是什么业务。pidbigint后台线程ID。即运行此SQL的线程的线程号,此线程号在pg_thread_wait_status/pg_locks等视图中也存在,可以用这个线程号来与这些视图进行关联。usesysidoid登录该后台的用户OID。usenamename登录该后台的用户名。执行此SQL的用户名,可以用来确认是什么用户调起的业务。application_nametext连接到该后台的应用名。应用名称,一般有三种:l gsql:此SQL是从gsql客户端发起l Data Studio:从Data Studio客户端发起的SQLl cn_50XX:代表从远端CN发送过来的SQL语句,一般出现在DDL、DCL、analyze、vacuum作业场景下l 其它:其它业务客户端发起的业务连接,如果应用程序未显式命名application_name,数据侧一般显式为unkonwnclient_addrinet连接到该后台的客户端的IP地址。 如果此字段是null,它表明通过服务器机器上UNIX套接字连接客户端或者这是内部进程(如autovacuum)。可以用来确定是从哪个机器发起的连接,进而帮助确认是什么业务发起的语句client_hostnametext客户端的主机名,这个字段是通过client_addr的反向DNS查找得到。这个字段只有在启动log_hostname且使用IP连接时才非空。client_portinteger客户端用于与后台通讯的TCP端口号,如果使用Unix套接字,则为-1。通过此字段圈定业务SQL发起客户端backend_starttimestamp with time zone该后台线程启动的时间,即当客户端连接到服务器的时间。xact_starttimestamp with time zone启动当前事务的时间,如果没有事务是活跃的,则为null。如果当前查询是首个事务,则这列等同于query_start列。如果启用了显式事务,即使用begin/start transaction等开启了一个事务,则此字段代表事务开始的时间。query_starttimestamp with time zone开始当前活跃SQL的开始时间, 如果state的值不是active,则这个值是上一个SQL的开始执行时间state_changetimestamp with time zone上次state字段值变化的时间。waitingboolean如果后台当前正等待锁则为true,否则为falseenqueuetext工作负载管理资源状态。· 语句当前的排队情况,包括:· Global::在全局队列中排队。 · Respool:在资源池队列中排队。 · CentralQueue:在中心协调节点(CCN)中排队。 · Transaction:语句处于一个事务块中排队。 · StoredProc : 语句处于一个存储过程中排队。 · None:未在排队。 · Forced None : 事务块语句或存储过程语句由于超出设定的等待时间而强制执行。上面这些状态表明了当前语句的排队情况,如果处在排队状态,语句是不在执行的,也不会占用系统资源。statetext该后台当前总体状态。状态值可能是如下的一种:· active:后台正在执行一个作业。 · idle:后台线程空闲,且不在一个事务块中。 · idle in transaction:后台线程空闲,且在事务块中· idle in transaction (aborted):后台线程空闲,且后台线程在事务块中有语句执行失败且没有执行rollback命令 · fastpath function call:后台正在执行一个fast-path函数。 · disabled:如果后台禁用track_activities,则报告这个状态。resource_poolname用户作业关联的资源池。query_idbigint查询语句的ID。当前语句的唯一标识,可以用此字段与pg_thread_wait_status关联。进一步进行问题分析定位querytext该后台的最新查询。如果state状态是active(活跃的),此字段显示当前正在执行的查询。所有其他情况表示上一个查询。语句默认仅显示1024字节。

 

pgxc_thread_wait_status  ☆☆☆☆

查询集群全局所有线程的层次调用关系及阻塞等待情况通常在视图查询语句增加其他过滤条件(比如根据pgxc_stat_activity筛选出来的疑似hangSQLquery_id),缩小关注排查范围

【附视图各字段含义

字段名称数据类型字段含义描述node_nametext实例的名称。db_nametext数据库名称。thread_nametext线程名称。query_idbigint业务SQL的ID编号,同一条SQL对应的所有的执行线程的query_id是相同的,与pg_stat_activity中query_id一致tidbigint当前线程的线程号。与pgxc_stat_activity中的pid、pg_locks中的pid一致lwtidinteger当前线程的轻量级线程号。使用此线程号可以在所在节点上进行gstack获取此线程运行栈信息ptidintegerstreaming线程的父线程号tlevelintegerstreaming线程的层级。与执行计划的层级(id)相对应。smpidintegersmp执行模式下并行线程的并行编号。wait_statustext当前线程的等待状态。等待状态的详细信息请参见资料。一般常见的状态有:wait node:dn_xxxx_xxxx:表示在等待某个DNnone:表示正在执行,没有等待任何其他节点acquire lock :表示正在等待锁。这时需要到对应节点上查看pg_locks视图。

 

pg_thread_wait_status  ☆☆☆☆

单个实例所有作业线程的层次调用关系及阻塞等待情况,在大集群复杂query问题定位时,视图pgxc_thread_wait_status返回的信息过多,会对问题定位形成一定干扰这时可以CN通过execute direct on语法获取指定dn实例的作业线程信息。比如要获取dn_6001_dn_6002节点的作业线程调用信息

 

pgxc_comm_recv_stream  ☆☆☆

查询集群所有DN通信库接收流状态,辅助通信发生收发Hang的排查定位。

pgxc_comm_send_stream  ☆☆☆

查询集群所有DN通信库发送流状态,pgxc_comm_recv_stream视图结合使用,来定位通信层的收发Hang问题

pgxc_prepared_xacts  ☆☆

查询集群所有节点启动事务信息,辅助事务超时场景下的Hang问题定位,通过查询视图获取gxid然后结合pgxc_xacts_iscommitted(gxid)可以获知事务是否提交。

pgxc_running_xacts  ☆☆

查询集群中所有节点的运行事务信息

pg_locks  ☆☆

查询当前实例的锁状态辅助死锁等待的Hang问题定位

名称类型引用描述locktypetext-被锁定对象的类型:relation,extend,page,tuple,transactionid,virtualxid,object,userlock,advisory。databaseoidPG_DATABASE.oid被锁定对象所在数据库的OID。· 如果被锁定的对象是共享对象,则OID为0。 · 如果是一个事务ID,则为NULL。relationoidPG_CLASS.oid表的OID,如果锁定的对象不是表,也不是表的一部分,则为NULL。锁等待一般都是等待表的锁,用relation做条件可以看到当前的表锁被谁持有。pageinteger-关系内部的页面编号,如果对象不是关系页或者不是行页,则为NULL。tuplesmallint-页面里边的行编号,如果对象不是行,则为NULL。virtualxidtext-事务的虚拟ID,如果对象不是一个虚拟事务ID,则为NULL。transactionidxid-事务的ID,如果对象不是一个事务ID,则为NULL。classidoidPG_CLASS.oid包含该对象的系统表的OID,如果对象不是普通的数据库对象,则为NULL。objidoid-对象在其系统表内的OID,如果对象不是普通数据库对象,则为NULL。objsubidsmallint-对于表的一个字段,这是字段编号;对于其他对象类型,这个字段是零;如果这个对象不是普通数据库对象,则为NULL。virtualtransactiontext-持有此锁或者在等待此锁的事务的虚拟ID。pidbigint-持有或者等待这个锁的服务器线程的逻辑ID。如果锁是被一个预备事务持有的,则为NULL。语句pid,可以看到这个pid是在等待哪几各锁,持有哪几各锁。modetext-这个线程持有的或者是期望的锁模式。grantedboolean-· 如果锁是持有锁,则为TRUE。 · 如果锁是等待锁,则为FALSE。表示锁被谁持有fastpathboolean-如果通过fast-path获得锁,则为TRUE;如果通过主要的锁表获得,则为FALSE。

 

pgxc_node  ☆☆

查询集群所有实例节点信息,重点关注节点的node_name, node_port, node_id

除过上述常用视图,Hang问题定位过程需要根据实际场景,结合执行计划、gstack工具、系统日志共同分析定位。

1.2 简单示例

比如在执行create table时候疑似发生hang,那么我们可以执行以下操作定位问题

1. 获取疑似hangSQLquery_id

select * from pgxc_stat_activity where state = ‘active’ and lower(query) like ‘create table %’;

2. 获取此作业的线程等待关系

select * from pgxc_thread_wait_status where query_id = xx;

xx为上一步获取的疑似hangSQLquery_id 

分析此query_id相关的线程的状态(字段wait_status),查看是否有acquire lock状态的线程,找到其node_name  tid字段

3. 对应的node_name上获取锁信息

execute direct on (xx) ‘select * from pg_locks where pid = xxx’;

--xx: 上一步获取的node_name字段的值

--yy上一步获取的tid字段值

获取等待加锁的信息(字段relation)

4.到对应的node_name上获取此表的持锁信息

execute direct on (xx) ‘select * from pg_locks where relation = yy and granted = true’;

--xx: 第二步获取的node_name字段的值

--yy: 第三步获取的等待加锁字段的值

获取持锁的线程(字段pid)

5.获取持锁的作业信息

select * from pgxc_stat_activity where pid=xx;

--xx: 第四步获取持锁线程信息

字段query内容即为持锁线程信息,也是阻塞create table语句的作业信息

 

Hang问题分类

客户感知hang分为

1. 真实hang

一般是轻量级锁缺陷执行链路环状或者死循环执行。这种场景下作业永远无法执行

2. 执行慢:

业务执行慢,远远超出客户的预期客户侧产生hang的认知效果。这种问题最终需要通过调优解决

3. 等待:

因抢占不到锁资源,导致作业排队等待加锁。这种场景表现是要么作业执行时间边长,要么等待一段时间(一般20min)之后报锁超时的失败信息

 

根据以往的经验,局点常见hang问题有以下几

Hang问题定位方法及解决措施

3.1 基本步骤

Step1. cm_ctl query查询集群当前状态,确保集群状态正常;

Step2. gsql连接数据库,执行select * from pgxc_stat_activity查询目标查询的query_id有时候可以增加where state = ‘active’筛选活跃SQL

Step3. 执行select * from pgxc_thread_wait_status where query_id = xxx查询集群全局与之关联的所有线程的层次调用关系及阻塞等待情况。自上而下,逐层分析,确定疑似阻塞节点及线程信息,甚至,可以绘制线程等待关系图,更加直观地分析当前Hang问题的根因。除此,可结合执行计划gstack查看线程堆栈,进一步佐证定位结论

Step4. 如果Step3无定论,则针对其他常见Hang场景(目前以锁等待和通信收发等待最为常见),结合2.1相应视图,进一步分析定位:

a) 等待:Step3查询结果分析线程等待关系,如果阻塞线程状态为acquire lock则进一步执行select * from pg_locks where pid = xxx查询阻塞线程的加锁情况;

b) 通信数据收发成环:从Step3的查询结果分析线程等待关系,如果阻塞线程状态一直flush data: wait quota则可能是通信层收发过程hang,继续执行select * from pgxc_comm_send_streamselect * from pgxc_comm_recv_stream,可以根据Step3查询结果增加where条件限定node_nameremote_namequery_idpn_id(plevel),进一步排查wait quota根因是否是发送端或接收端数据流异常或者通信问题


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

评论(0

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

全部回复

上滑加载中

设置昵称

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

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

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