今天快下班的时候,业务的同学找到我,我猜这种情况下是有应用的问题了。
他们反馈说在做一个GP端的函数变更时,长时间没有响应。
我看了下GP Master端,看到负载并不高,当然这是一个初步的检测,如果集群响应缓慢,则很可能是segment节点上出现了延迟。一看则吓一跳,这是一个segment节点的load负载。
负载高达20多,这负载简直是太高了,难怪会出现很大的延迟。
没过一会就看到GPCC的提示,GP集群已经不可访问了。
GPCC端的提示如下:
简单验证,发现问题确实严重了,连接已经满了。
[gpadmin@tk-dat-test ~]$ psql
psql: FATAL: sorry, too many clients already
这个时候一种快速的方式就是先停止GPCC的相关进程。GPCC是GP集群定制的B/S端管理软件,比较轻量方便。
[gpadmin@tk-dat-test~]$ gpcmdr --status gpcc211
==Greenplum Command Center UI for instance 'gpcc211' - [RUNNING on PORT: 28080]==
Lighttpd (pid 3775) is running...
Python gpmonws.py (pid 3776) is running...
Beta server (pid 3796) is running on port: 28090
先停掉GPCC的进程。
[gpadmin@tk-dat-test~]$ gpcmdr --stop gpcc211
Stopping instance gpcc211... killing pid 3775
killing beta server pid 3796
Done.
然后查看GP集群里的会话情况,可以看到相关的进程有差不多30多个。
testDB=# select procpid ,usename from pg_stat_activity where datname = 'gpperfmon';
我们可以使用如下的方式来生成批量停止会话的语句。
select 'select pg_terminate_backend('||procpid||');' from pg_stat_activity where datname = 'gpperfmon';
值得一提的是在其中一个segment节点上,查看gpmon相关的进程竟然有200多个。
[yangjr01@tk-dat-test~]$ ps -ef|grep gpmon|wc -l
276
可见资源的占用情况是很严重的。
这个问题可以间接的理解为,应用端触发了问题,gpmon监控程序处于无响应状态,gpmon持续发起新的请求,结果资源占用溢出,GP集群不可用。
解决的初步方法是:
停止GPCC的相关进程,批量生成停止会话的语句。
大概过了有10分钟,系统的负载从20降到了7左右。但是显然问题的处理陷入了僵局,因为僵死的会话迟迟无法释放,所以和同事商量,我们可以快速的修复,可以考虑使用重启GP集群来强制释放僵死的会话。
gpstop -M fast
gpstart
至于问题的原因,在问题修复之后和业务同学沟通,很可能的原因是在一个在执行中的任务,他们手工修改了函数的定义信息,结果这个操作就卡在那里了。一种相对更加稳妥的方式就是先把正在执行的任务都停止了,才可以做函数存储过程的变更。