1. 集群版本
GaussDB A 8.0及6.5.1版本
2. 影响范围
应急处理后立即恢复
3. 问题描述
客户端连接数据库、查询语句等,报错连接已满:too many clients already, active/non_active: xxxx/xxxx.

4. 数据收集
报错某个DN上连接满:
1. pooler视图看连接(所有CN上都要查,加起来就是结果):
select in_use, count(*) from pg_pooler_status where node_name = 'dn_xxxx_xxxx' group by 1;
2. netstat直接看连接:
找DN目录:cm_ctl query -Cvd | grep dn_xxxx_xxxx 找DN进程:ps ux | grep 上一步找到的目录 统计连接数量:netstat -anpt | grep pid | wc -l
报错CN上连接满:
1. 检查session_timeout;
show session_timeout;
2. 连接处于idle状态的客户端(cn_5001登录不上,可以在其他CN上登录;任意指定字段查需要的信息,以下sql仅供参考):
select usename, application_name, client_addr, count(*) from pgxc_stat_activity where state = 'idle' and coorname = 'cn_xxxx' group by 1, 2, 3 order by 4 desc; select usename, application_name, query_start from pgxc_stat_activity where state = 'idle' and coorname = 'cn_xxxx' group by 1, 2, 3 order by 3 desc; ...
3. 对应的pooler中存储的连接状态;
show persistent_datanode_connections; select pooler.node_name, pooler.in_use, count(*) from pg_pooler_status pooler, pgxc_stat_activity activity where pooler.tid = activity.pid and activity.state = 'idle' group by 1, 2 order by 3 desc;
5. 问题分析 :
DN和CN上报此错误是有差别的,DN上是因为CN与DN的连接数满,可用clean connection清理;而CN上多半是由于客户端的连接不释放导致,更多时候需要核查业务。
报错DN上连接满:
1. clean connection to node (dn_xxxx_xxxx/cn_xxxx) [all] for database dbname;
dn_xxxx_xxxx:报错的DN;dbname:指定数据库;
灵活清理,既可指定报错DN,也可指定与报错DN相连的所有CN,更可以直接all;
缺点:clean connection只能清理CN的pooler上与DN的in_use为f的连接,新版本DN上连接达到max_connections时,会自动清理每个pool的四分之一的空闲连接;
2. kill dn_xxxx_xxxx;
找DN目录:cm_ctl query -Cvd | grep dn_xxxx_xxxx 找DN进程:ps ux | grep 上一步找到的目录 kill -9 pid
缺点:kill进程的确是应急最快释放连接的方法,然而对于in_use为t的连接,可能是正有业务在执行的连接,随意kill会对业务有短暂的影响。
3. 如果开启了persistent_datanode_connections,释放掉CN上为idle的连接或关闭此参数;
操作步骤如下:CN上连接满
原因:有客户端连接CN结束业务后没有释放,连接一直保持为idle状态,但是由于参数persistent_datanode_connections开启,CN与DN的连接一直被占有,即in_use为t,因此清理掉这些CN上的连接是有效的一种手段;
4. GUC参数max_connections;
原因:CN和DN上的max_connections设置是有依据的,理论上,DN上设置应为CN上的值 * CN的数量,核查一下,说不定真的是DN上不够了!
报错CN上连接满:
1. session_timeout;
idle状态的连接有很多且一直保留着,很有可能没有开启session_timeout,设置超时时间后,会自动清理;
缺点:客户端如果超过这个值没有进行操作,那么连接就会被数据库侧断开,业务侧使用这个连接就会报错:An I/O occured while sending to the backend;
2. kill连接线程;
select pid, state from pgxc_stat_activity; select pg_terminate_backend(pid);
缺点:任意线程都能清,但是分析不到根因,日后还是容易复发;
3. kill cn_xxxx;
连此cn上的业务都会有影响,且容易无法分析根因,但是应急快、效果好;
4. 排查业务侧哪些连接没有释放,原因大多是业务引发;
业务侧重点排查连接池对idle状态连接的管控;
原创文章,作者:奋斗,如若转载,请注明出处:https://blog.ytso.com/tech/bigdata/316542.html