How to Shell Script to execute SQL scripts( kill session) using psql/gsql for openGauss or PostgreSQL?
Postgresql系为了避免像oracle ora-1555的问题,使用非undo的机制, 但需要周期性的做VACUUM,否则表上的dead tuples就没有办法复用或回收。 并且在PG或OG数据库Vacuum的最老位置是系统级的,如果有一个长事务存在,那长事务时间的其它表也没办法Vacuum,因为它不确认你是否会查其它表, 随时间推移,对于update,delete较多的表就会导致表膨胀较为明显,影响系统性能, 如果无法限制应用,此时可以定期的KILL一些长事务会话,如个人客户端,我们可以加一个shell到crontab中定期自动清理。
#!/bin/sh # file : kill_longtx.sh # author : weizhao zhang(anbob.com) # purpose: Shell script to execute gsql command KILL Sessions in openGauss long than 30s LOGPATH=/home/og/log if [ ! -d "$LOGPATH" ];then mkdir $LOGPATH if [ $? -ne 0 ] then echo "$LOGPATH not exists and create failed!" exit 90 fi fi LOGFILE=$LOGPATH/kill_longtx.log SQLLOG=$LOGPATH/killed_sessions.log SQLSCRIPT=$LOGPATH/kill_longtx.sql # SQLLOG=$LOGPATH/killed`date +"%Y_%m_%d_%H_%M"`.log if [ ! -f "$SQLSCRIPT" ];then mkdir $LOGPATH if [ $? -ne 0 ] then echo "$SQLSCRIPT not exists!" exit 90 fi fi #Set the value of variable DATABASE="anbob" PORT=6432 echo " " >> $LOGFILE 2>&1 echo "START ----`date`" >> $LOGFILE 2>&1 #Assign table count to variable SESSION_COUNT=$(gsql -d $DATABASE -p $PORT -t -c "select count(1) from pg_stat_activity where state='idle in transaction' and extract(epoch FROM now() - query_start)>30") if [ $SESSION_COUNT -gt 0 ] then #Print the value of variable echo "Found long transaction sessions:$SESSION_COUNT " >> $LOGFILE 2>&1 #Execute few psql commands: gsql -d $DATABASE -p $PORT -a -q -f $SQLSCRIPT -L $SQLLOG gsql_exit_status = $? if [ $gsql_exit_status != 0 ]; then echo "gsql failed while trying to run this sql script" >> $LOGFILE 2>&1 exit $psql_exit_status fi else echo "Not found long transaction sessions:$SESSION_COUNT " >> $LOGFILE 2>&1 fi echo "END ----`date`" >> $LOGFILE 2>&1
Note:
注意我这里使用了是openGauss, 所以是gsql命令行工具,如果是postgresql可以替换为psql通用, 逻辑是调用kill_longtx.sh 检查一些有事务的会话,这里过滤的是近期无活动的30s以上的会话,如果你是oracle dba,可以理解为last_call_et > 30s。 当然你可以增加自己的过滤条件,如application like. 如果个数>0 执行kill_longtx.sql脚本,中调用pg_terminate_backend() 终止了会话, 期间会记录日志(每次的调用和KILL的会话)。
gsql的使用的几个参数选项。
# -h PostgreSQL server IP address
# -d database name
# -U user name
# -p port which PostgreSQL server is listening on
# -f path to SQL script
# -a all echo
# -q quiet
# -o spool output to file
# -L send session log to file
kill_longtx.sql
-- kill long tx by xx client -- log datetime select now(); -- log session and kill session select datid,datname,pid,sessionid,usename,application_name,backend_start,xact_start,query_start,waiting,state,extract(epoch FROM now() - query_start) waited ,pg_terminate_backend(pid) from pg_stat_activity where state='idle in transaction' and extract(epoch FROM now() - query_start)>30;
ok ,然后就可以在crontab中增加调度,调用像kill_longtx.sh定期做一些事情。
对不起,这篇文章暂时关闭评论。