【云小课】EI第34课 运筹帷幄-GaussDB(DWS)教你分析阻塞SQL的几个妙招

举报
Hi,EI 发表于 2021/11/15 11:14:47 2021/11/15
【摘要】 在开发过程中,开发者常遇到SQL连接数超限、SQL查询时间过长、SQL查询阻塞等问题,您可以通过PG_STAT_ACTIVITY视图来分析和定位SQL问题,以下展示常用的一些定位思路。

在开发过程中,开发者常遇到SQL连接数超限、SQL查询时间过长、SQL查询阻塞等问题,您可以通过PG_STAT_ACTIVITY视图来分析和定位SQL问题,以下展示常用的一些定位思路。


云小课插图.jpg

表1 部分PG_STAT_ACTIVITY字段


名称 类型 描述
usename

name

登录该后端的用户名。
client_addr inet 连接到该后端的客户端的IP地址。 如果此字段是null,则表示通过服务器机器上UNIX套接字连接客户端或者这是内部进程,如autovacuum。
application_name text 连接到该后端的应用名。
state

text

后端当前总体状态。可能值是:

  • active:后台正在执行查询。

  • idle:后台正在等待新的客户端命令。

  • idle in transaction:后端在事务中,但事务中没有语句在执行。

  • idle in transaction (aborted):后端在事务中,但事务中有语句执行失败。

  • fastpath function call:后端正在执行一个fast-path函数。

  • disabled:如果后端禁用track_activities,则报告此状态。

3.PNG普通用户只能查看到自己帐户所对应的会话状态。即其他帐户的state信息为空。

waiting

boolean

如果后端当前正等待锁则为true。

enqueue

text

语句当前排队状态。可能值是:

  • waiting in queue:表示语句在排队中。

  • waiting in global queue:表示语句在全局排队中。

  • waiting in respool queue:表示语句在资源池排队中。

  • waiting in ccn queue:表示作业在CCN排队中。

  • 空:表示语句正在运行。

pid

bigint

后端线程ID。



查看连接信息

  • 通过以下SQL就能确认当前的连接用户、连接地址、连接应用、状态、是否等待锁、排队状态以及线程id。

    SELECT usename,client_addr,application_name,state,waiting,enqueue,pid FROM PG_STAT_ACTIVITY WHERE DATNAME='数据库名称';

    回显如下

    usename | client_addr | application_name | state | waiting | enqueue | pid
    
    ---------+---------------+------------------+--------+---------+---------+-----------------
    
    leo | 192.168.0.133 | gsql | idle | f | | 139666091022080
    
    dbadmin | 192.168.0.133 | gsql | active | f | | 139666212681472
    
    joe | 192.168.0.133 | | idle | f | | 139665671489280
    
    (3 rows)
  • 中止某个会话连接(仅系统管理员有权限)

    SELECT PG_TERMINATE_BACKEND(pid);

查看SQL运行信息

  • 获取当前用户执行SQL信息:

    SELECT usename,state,query FROM PG_STAT_ACTIVITY WHERE DATNAME='数据库名称';
    回显如下,如果state为active,则query列表示当前执行的SQL语句,其他情况则表示为上一个查询语句。
    usename | state | query
    
    ---------+--------+---------------------------------------------------------------------------
    
    leo | idle | select * from joe.mytable;
    
    dbadmin | active | SELECT usename,state,query FROM PG_STAT_ACTIVITY WHERE DATNAME='gaussdb';
    
    joe | idle | GRANT SELECT ON TABLE mytable to leo;
    
    (3 rows)
  • 查看当前正在运行(非idle)的SQL信息:

    SELECT datname,usename,query FROM PG_STAT_ACTIVITY WHERE state != 'idle' ;

查看耗时较长的语句

  • 查看当前运行中的耗时较长的SQL语句

    SELECT current_timestamp - query_start as runtime, datname, usename, query FROM PG_STAT_ACTIVITY WHERE state != 'idle' order by 1 desc;

    查询会返回按执行时间长短从大到小排列的查询语句列表。第一条结果就是当前系统中执行时间最长的查询语句。

    runtime | datname | usename | query
    
    -----------------+----------+---------+-----------------------------------------------------------------------------------------------------------------------------------------
    
    00:04:47.054958 | gaussdb | leo | insert into mytable1 select generate_series(1, 10000000);
    
    00:00:01.72789 | gaussdb | dbadmin | SELECT current_timestamp - query_start as runtime, datname, usename, query FROM PG_STAT_ACTIVITY WHERE state != 'idle' order by 1 desc;
    
    (2 rows)
  • 若当前系统较为繁忙,可以通过限制current_timestamp - query_start大于某一阈值来查看执行时间超过此阈值的查询语句。

    SELECT query from PG_STAT_ACTIVITY WHERE current_timestamp - query_start > 2;

查看处于阻塞状态的语句

  • 查看当前处于阻塞状态的查询语句:

    SELECT pid, datname, usename, state, query FROM PG_STAT_ACTIVITY WHERE state <> 'idle' and waiting=true;
    执行以下语句结束到阻塞的SQL会话。
    SELECT PG_TERMINATE_BACKEND(pid);

    截图.PNG

    • 大部分场景下,阻塞是因为系统内部锁而导致的,waiting字段才显示为true,此阻塞可在视图pg_stat_activity中体现。

    • 在一些少数场景下,例如写文件、定时器等情况的查询阻塞,不会在视图pg_stat_activity中体现。


  • 查看阻塞的查询语句及阻塞查询的表、模式信息

    SELECT w.query as waiting_query,
    
    w.pid as w_pid,
    
    w.usename as w_user,
    
    l.query as locking_query,
    
    l.pid as l_pid,
    
    l.usename as l_user,
    
    t.schemaname || '.' || t.relname as tablename
    
    from pg_stat_activity w join pg_locks l1 on w.pid = l1.pid
    
    and not l1.granted join pg_locks l2 on l1.relation = l2.relation
    
    and l2.granted join pg_stat_activity l on l2.pid = l.pid join pg_stat_user_tables t on l1.relation = t.relid
    
    where w.waiting;

    该查询返回会话ID、用户信息、查询状态,以及导致阻塞的表、模式信息。

    查询到阻塞的表及模式信息后请根据会话ID结束会话。

    SELECT PG_TERMINATE_BACKEND(pid);



2.jpg想要了解更多华为云数据仓库GaussDB(DWS),请猛戳!!!

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

评论(0

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

全部回复

上滑加载中

设置昵称

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

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

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