转载请注明出处:gpdb删除segment上残余的session和sql

最近公司的gpdb的变卡,导致线上系统查询队列阻塞,用户一点数据都查不出来。

每天早上我和同事都得用我们自家做的gpdb运维平台去杀掉生产的sql,让消费sql能跑起来

但每天这么杀sql也不是事,而且平常生产sql是执行很快的,但不知道为什么gpdb启动时间变长后,修改sql就变慢了(运维平台上显示正在运行很久),重启gpdb后,sql会变得很快

遇到这种系统运行时间久,系统变慢的问题,我们第一反应是gpdb有内存泄漏问题。组长看过gpdb的很多ppt,说可能是segment上残余进程(session、sql)引起的,这些会占用锁和内存。

于是和另一个同事研究这个问题,最终搞定了这个问题

首先用建立一张外部网络表用utility模式查询segment上的所有session

CREATE EXTERNAL WEB TABLE get_segment_mpp_session_info (segment_id integer, mpp_session_id integer, start_time bigint)
EXECUTE 'PGOPTIONS="-c gp_session_role=utility" psql -tA -p $GP_SEG_PORT -d da_common -c "select distinct $GP_SEGMENT_ID, mppsessionid, extract(epoch from backend_start)::int from pg_locks left join pg_stat_activity on pg_locks.pid=pg_stat_activity.procpid"'
FORMAT 'TEXT' (DELIMITER '|');

然后join过滤出segment有而master没有的查询, 注意where条件过滤时间可以排除此条sql

with
segment_sql_info as (select * from get_segment_mpp_session_info),
distinct_segment_session_id as (select distinct mpp_session_id from segment_sql_info),
distinct_master_session_id as (select distinct mppsessionid from pg_locks)
select segment_sql_info.*
from
(
select mpp_session_id
from distinct_segment_session_id
left join distinct_master_session_id
on mpp_session_id = mppsessionid
where mppsessionid is null
) loss_id
join segment_sql_info
on loss_id.mpp_session_id = segment_sql_info.mpp_session_id
where start_time < extract(epoch from now())::int

最后稍微改改上面的sql,用utility模式去各个segment杀session就行

with segment_sql_info AS
(SELECT * FROM get_segment_mpp_session_info), distinct_segment_session_id AS
(SELECT DISTINCT mpp_session_id FROM segment_sql_info), distinct_master_session_id AS
(SELECT DISTINCT mppsessionid FROM pg_locks)
SELECT 'PGOPTIONS=''-c gp_session_role=utility'' psql -tA -h ' || address || ' -p '|| port || ' -d da_common -c "select pid, pg_terminate_backend(pid), current_query from pg_locks pgl left join pg_stat_activity pgsa ON pgl.pid = pgsa.procpid WHERE mppsessionId=' || mpp_session_id || ' group by pid, current_query"'
FROM
(SELECT segment_sql_info.*
FROM
(SELECT mpp_session_id
FROM distinct_segment_session_id
LEFT JOIN distinct_master_session_id
ON mpp_session_id = mppsessionid
WHERE mppsessionid is NULL ) loss_id
JOIN segment_sql_info
ON loss_id.mpp_session_id = segment_sql_info.mpp_session_id
WHERE start_time < extract(epoch
FROM now())::int ) info
LEFT JOIN gp_segment_configuration
ON segment_id = dbid

后来在变卡的时候,跑一跑上面的sql,生成shell命令去每个segment去杀session,生产sql直接就变快了。我们写成contab去定时杀,这样就不用人工清理了。

需要注意的

  1. 上面的sql查出的残余session,可能只是短时间残余,过几秒后自己会被gpdb自己清掉
  2. 使用pg_terminate_backend函数可能杀不掉MPP查询进程,这时需要去segment去执行kill -9

回顾一下gpdb变慢的过程

  1. 线上提交了一条DML sql,打开了写锁
  2. 可能超时、网络不好、内存不足等原因,这条sql查询失败
  3. gpdb尝试删除这条sql在master和segment上的相关信息,但是可能由于网络等原因没有清掉某些segment的信息(进程、session事务、锁)
  4. 提交消费sql,gpdb在master看不到相关的锁信息,于是让生产sql在master上分配一个读锁,并尝试在segment上分配读锁
  5. 在某些含有残余session的segment上,由于之前的写锁未释放,所以读锁也获取不了,虽然查询在master上认为已经运行了,但实际上segment上的读操作会被一直阻塞

最后吐槽一下gpdb,session残余的问题都没处理好╭∩╮(︶︿︶)╭∩╮

gpdb删除segment上残余的session和sql的更多相关文章

  1. 如何实现Outlook 2010 下载邮件后自动删除服务器上的邮件

    outlook2010---文件---信息---账户设置---选中要设置的帐号---双击点选要设置的邮箱---其他设置---高级---在服务器上保留邮件的副本---14天后删除服务器上的邮件副本,修改 ...

  2. 如何删除 Ubuntu 上不再使用的旧内核

    提问:过去我已经在我的Ubuntu上升级了几次内核.现在我想要删除这些旧的内核镜像来节省我的磁盘空间.如何用最简单的方法删除Ubuntu上先前版本的内核? 在Ubuntu上,有几个方法来升级内核.在U ...

  3. Visio中添加、移动或删除形状上的连接点的方法

    Visio中添加.移动或删除形状上的连接点的方法 利用Visio画图时,学会使用连接点能使你的画图质量和速度大幅度提高.下面在Visio2010中,以一个例子讲述如何使用连接点. 一. 准备 1. 打 ...

  4. 使用 vscode将本地项目上传到github以及删除github上的某个文件夹

    安装Git后,可以看到windows环境下有两个命令输入窗口Git CMD 和Git Bash Git GUI是可视化图形界面 Git中的Bash是基于CMD的,在CMD的基础上增添一些新的命令与功能 ...

  5. hibernate session.createSQLQuery(sql); 通过命令删除

    @Override public boolean deleteBySql(String sql) { Session session = getSession(); @SuppressWarnings ...

  6. 转载:删除github上文件夹的两种方式

    http://www.jianshu.com/p/286be61bb9b8 删除github上文件夹的两种方式(解决已经加入ignore的文件夹无法从远程仓库删除的问题) 如果此文件夹已被加入git追 ...

  7. Docker registry 私有仓库镜像查询、删除、上传、下载 shell

    #Docker官方私有仓库registry #官方只提供了API接口,不方便使用,就写了个shell #docker-registry安装配置http://www.cnblogs.com/elvi/p ...

  8. 使用git工具删除github上的文件或者文件夹

    解决 使用git工具删除github上的文件或者文件夹 当我们需要从github上删除一些我们不需要的文件或者文件夹时,如果通过github来操作的话,将会很麻烦,因为github只允许删除一个仓库, ...

  9. 删除gitlab上的分支

    好久没有更新了, 今天记录一下删除gitlab上的分支的操作 登录仓库后, 依次点击: project --> home --> Readme --> repository --&g ...

随机推荐

  1. python下载网页转化成pdf

    最近在学习一个网站补充一下cg基础.但是前几天网站突然访问不了了,同学推荐了waybackmachine这个网站,它定期的对网络上的页面进行缓存,但是好多图片刷不出来,很憋屈.于是网站恢复访问后决定把 ...

  2. C++12.1.4 类的前向声明、不完全类型类

    只声明却没有定义的类称为—————–不完全类型,不完全类型不能定义该类型的对象,只能用于定义指向该类型的指针及引用,或者用于声明(不是定义)使用该类型作为形参类型或返回类型的函数. 在创建类的对象之前 ...

  3. SpringBoot学习笔记(13)----使用Spring Session+redis实现一个简单的集群

    session集群的解决方案: 1.扩展指定server 利用Servlet容器提供的插件功能,自定义HttpSession的创建和管理策略,并通过配置的方式替换掉默认的策略.缺点:耦合Tomcat/ ...

  4. 洛谷P2607 [ZJOI2008]骑士 基环树动归

    Code: #include<algorithm> #include<cstdio> #include<algorithm> #include<cstring ...

  5. docker私有仓库yum安装 docker-registry

    [root@riyimei-node1:/root]> yum install docker-registryLoaded plugins: fastestmirror, langpacksLo ...

  6. WPF 获取应用的所有窗口

    原文:WPF 获取应用的所有窗口 本文告诉大家如何获取应用内的所有窗口,无论这些窗口有没显示 在 WPF 可以通过 Application.Current.Windows 列举应用的所有窗口 fore ...

  7. C语言计算字符串数组中每个字符串出现的个数

    unsigned int str_num(char *str[], int num[], int len) { int i, j; int count; int flag[len]; ; i < ...

  8. 利用hive源码解析sql查了哪些表哪些字段

    在hiveserver2中使用了org.apache.hadoop.hive.ql.parse.BaseSemanticAnalyzer对抽象语法树(AST)进行语义分析,分析的过程可以得出hive查 ...

  9. 大海教你学手游2015CocosLua第一季_00课程介绍

    话说大盘从5100直掉到3500点,千仅仅股票跌幅超过20%,跌跌不休.散户.证监会.做空机构開始斗气地主来了: 散户:叫地主 空头:抢地主,3分 证监会:pass 空头:压死 证监会:不要 散户:不 ...

  10. 漫谈linux之文件IO篇(SSD写性能和机械硬盘差不多,读是4到10倍)

    前同事的文章,觉得写得很清晰,收藏了. http://blog.chinaunix.net/uid-27105712-id-3270102.html 在Linux 开发中,有几个关系到性能的东西,技术 ...