GaussDB for DWS Hang问题定位指南

网友投稿 599 2022-05-30

1 Hang问题基础知识

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

1.1 常用视图

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

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

pgxc_stat_activity ☆☆☆

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

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

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

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

【附:视图各字段含义】

pgxc_thread_wait_status  ☆☆☆☆☆

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

【附:视图各字段含义】

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问题定位。

pgxc_node  ☆☆

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

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

1.2 简单示例

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

GaussDB for DWS Hang问题定位指南

1. 获取疑似hang的SQL的query_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:为上一步获取的疑似hang的SQL的query_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语句的作业信息

2 Hang问题分类

客户侧感知的hang分为三种

1. 真实hang

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

2. 执行慢:

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

3. 锁等待:

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

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

3 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_stream和select * from pgxc_comm_recv_stream,可以根据Step3的查询结果增加where条件限定node_name、remote_name、query_id、pn_id(即plevel),进一步排查wait quota的根因是否是发送端或接收端数据流异常或者通信问题等。

任务调度 数据仓库服务 GaussDB(DWS) SQL

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:谈 Kubernetes 的架构设计与实现原理
下一篇:闭关多日,整理一份C++中那些重要又容易忽视的细节
相关文章