• 沒有找到結果。

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

4-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,则 报告此状态。

说明

普通用户只能查看到自己帐 户所对应的会话状态。即其 他帐户的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。

查看连接信息

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;

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

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);

说明

● 大部分场景下,阻塞是因为系统内部锁而导致的,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);