gpdb删除segment上残余的session和sql
转载请注明出处: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去定时杀,这样就不用人工清理了。
需要注意的
- 上面的sql查出的残余session,可能只是短时间残余,过几秒后自己会被gpdb自己清掉
- 使用pg_terminate_backend函数可能杀不掉MPP查询进程,这时需要去segment去执行kill -9
回顾一下gpdb变慢的过程
- 线上提交了一条DML sql,打开了写锁
- 可能超时、网络不好、内存不足等原因,这条sql查询失败
- gpdb尝试删除这条sql在master和segment上的相关信息,但是可能由于网络等原因没有清掉某些segment的信息(进程、session事务、锁)
- 提交消费sql,gpdb在master看不到相关的锁信息,于是让生产sql在master上分配一个读锁,并尝试在segment上分配读锁
- 在某些含有残余session的segment上,由于之前的写锁未释放,所以读锁也获取不了,虽然查询在master上认为已经运行了,但实际上segment上的读操作会被一直阻塞
最后吐槽一下gpdb,session残余的问题都没处理好╭∩╮(︶︿︶)╭∩╮
gpdb删除segment上残余的session和sql的更多相关文章
- 如何实现Outlook 2010 下载邮件后自动删除服务器上的邮件
outlook2010---文件---信息---账户设置---选中要设置的帐号---双击点选要设置的邮箱---其他设置---高级---在服务器上保留邮件的副本---14天后删除服务器上的邮件副本,修改 ...
- 如何删除 Ubuntu 上不再使用的旧内核
提问:过去我已经在我的Ubuntu上升级了几次内核.现在我想要删除这些旧的内核镜像来节省我的磁盘空间.如何用最简单的方法删除Ubuntu上先前版本的内核? 在Ubuntu上,有几个方法来升级内核.在U ...
- Visio中添加、移动或删除形状上的连接点的方法
Visio中添加.移动或删除形状上的连接点的方法 利用Visio画图时,学会使用连接点能使你的画图质量和速度大幅度提高.下面在Visio2010中,以一个例子讲述如何使用连接点. 一. 准备 1. 打 ...
- 使用 vscode将本地项目上传到github以及删除github上的某个文件夹
安装Git后,可以看到windows环境下有两个命令输入窗口Git CMD 和Git Bash Git GUI是可视化图形界面 Git中的Bash是基于CMD的,在CMD的基础上增添一些新的命令与功能 ...
- hibernate session.createSQLQuery(sql); 通过命令删除
@Override public boolean deleteBySql(String sql) { Session session = getSession(); @SuppressWarnings ...
- 转载:删除github上文件夹的两种方式
http://www.jianshu.com/p/286be61bb9b8 删除github上文件夹的两种方式(解决已经加入ignore的文件夹无法从远程仓库删除的问题) 如果此文件夹已被加入git追 ...
- Docker registry 私有仓库镜像查询、删除、上传、下载 shell
#Docker官方私有仓库registry #官方只提供了API接口,不方便使用,就写了个shell #docker-registry安装配置http://www.cnblogs.com/elvi/p ...
- 使用git工具删除github上的文件或者文件夹
解决 使用git工具删除github上的文件或者文件夹 当我们需要从github上删除一些我们不需要的文件或者文件夹时,如果通过github来操作的话,将会很麻烦,因为github只允许删除一个仓库, ...
- 删除gitlab上的分支
好久没有更新了, 今天记录一下删除gitlab上的分支的操作 登录仓库后, 依次点击: project --> home --> Readme --> repository --&g ...
随机推荐
- C++调用约定和名字约定 thiscall
调用约定: __cdecl __fastcall与 __stdcall,三者都是调用约定(Calling convention),它决定以下内容:1)函数参数的压栈顺序,2)由调用者还是被调用者把参数 ...
- 使用TensorFlow编写常用模块的Python代码示例
将数据转化成tfrecords的形式 import os import tensorflow as tf import numpy as np import matplotlib.image as m ...
- 路飞学城Python-Day16
- 洛谷3627 [APIO2009]抢掠计划
题目描述 输入格式: 第一行包含两个整数 N.M.N 表示路口的个数,M 表示道路条数.接下来 M 行,每行两个整数,这两个整数都在 1 到 N 之间,第 i+1 行的两个整数表示第 i 条道路的起点 ...
- Linux 磁盘管理及分区
硬盘结构和基础知识 扇区(Sector)为最小的物理储存单位,每个扇区为512 bytes,将扇区组成一个圆就是磁道(track),不同磁盘的相同磁道组成磁柱(Cylinder),磁柱是分区(par ...
- (51) magento集成增加到款通知
这篇主要讲述如何二开增加自己的功能,我没有继承方式二开,习惯是不好的,直接改了原来的模块. 达到效果就这样,当在网站支付成功,会同步到ERP系统中.下面来讲述实现过程 建立文件 payment_not ...
- 第一个JavaWeb工程
这个工程主要用来研究log4j,所以就只有一个页面,希望以后慢慢进步. java动态生成网页主要使用servlet.把请求拦截下来,处理后返回结果. 这里创建的是一个maven工程. 结构如下:
- C语言程序设计:现代方法阅读笔记
第二十六章 atexit函数允许用户“注册”在程序终止时要调用的函数:atexit(func); 在程序终止后,func函数会被自动调用 clock()函数可以计算程序运行时间 time函数返回当前的 ...
- JAVA关于byte数组与String转换的问题
1 public class ToString{ public static void main(String[] args){ String aa = "hellow"; byt ...
- 洛谷—— P2983 [USACO10FEB]购买巧克力Chocolate Buying
https://www.luogu.org/problem/show?pid=2983 题目描述 Bessie and the herd love chocolate so Farmer John i ...