解决PostgreSQL执行超时的情况

阅读: 评论:0

静压主轴解决PostgreSQL执⾏超时的情况
使⽤背景
最近在使⽤PostgreSQL的时候,在执⾏⼀些数据库事务的时候,先后出现了statement timetout 和idle-in-transaction timeout 的问题,导致数据库操作失败。
经研究查,PostgreSQL有关于SQL语句执⾏超时和事务执⾏超时的相关配置,⽽默认超时时间是10000毫秒,即10秒钟的时间,这样会导致执⾏时间稍长的任务执⾏失败。可以通过修改PostgreSQL服务器配置⽂件的⽅式修改默认配置。
参数说明
statement_timeout
statement_timeout 在 postgresql 被⽤来控制语句执⾏时长,单位是ms。
$ f
#statement_timeout = 0        # in milliseconds, 0 is disabled
默认是0,表⽰语句可以⼀直执⾏下去。
如果设置为10000,那就意味着语句最多可以执⾏ 10000ms = 10s。
建议设置为0,禁⽤该参数。
idle_in_transaction_session_timeout
星空轮PostgreSQL 9.6版本开始⽀持⾃动查杀超过指定时间的 idle in transaction 空闲事务连接,⽤于清理应⽤代码中忘记关闭已开启的事务,或者系统中存在僵死进程等。
idle_in_transaction_session_timeout 在 postgresql 被⽤来控制事务执⾏时长,单位是ms。
$ f
#idle_in_transaction_session_timeout = 0        # in milliseconds, 0 is disabled
默认是0,表⽰语句可以⼀直执⾏下去。超时会报 FATAL: terminating connection due to idle-in-transaction timeout。
修改⽅法
查配置
通过命令查到postgresql配置⽂件的位置,⽤vi进⾏编辑。
find / -name "f"
vi /var/lib/pgsql/9.6/f
修改参数
进⼊vi编辑界⾯,可以通过vi查命令定位到相关参数,修改成合适的时间,保存退出。
:/statement_timeout
重启配置
通过以下命令,查pg_ctl的位置,然后执⾏ pg_ctl reload重新加载配置。
find / -name "pg_ctl"
/usr/pgsql-9.6/bin/pg_ctl reload
PG_CTL⽤法
启动服务器
启动服务器:
$ pg_ctl start
启动服务器的⼀个例⼦,等到服务器启动了才退出:
$ pg_ctl -w start
服务器使⽤ 5433 端⼝,⽽且不带 fsync 运⾏,使⽤:
$ pg_ctl -o "-F -p 5433" start
停⽌服务器
$ pg_ctl stop
使⽤ -m 选项停⽌服务器允许⽤户控制如何关闭后端。
重启服务器
这个命令⼏乎等于先停⽌服务器然后再启动它,只不过 pg_ctl 保存并重新使⽤上⼀次运⾏服务器的命令⾏参数。重启服务器的最简单的⽅法是:
$ pg_ctl restart
dbr激光器重启服务器,等待其停⽌和重启:
$ pg_ctl -w restart
使⽤ 5433 端⼝重启并且重启后关闭 fsync :
$ pg_ctl -o "-F -p 5433" restart
显⽰服务器状态
下⾯是来⾃ pg_ctl 的状态输出的例⼦:
$ pg_ctl statuspg_ctl: server is running (pid: 13718)
Command line was:
/usr/local/pgsql/bin/postgres '-D' '/usr/local/pgsql/data' '-p' '5433' '-B' '128'
这就是在 restart 模式中被调⽤的命令⾏。
补充:PostgreSQL 设置单条SQL的执⾏超时 - 防雪崩
背景
设置单条SQL的执⾏超时,防雪崩。
通常来说可以在SQL发起前设置事务级超时参数,SQL执⾏结束,重置。(如果SQL异常退出,会⾃动重置事务级参数)例⼦
begin;
......
set local statement_time='100ms';
select count(*) from a;  -- 这条SQL的执⾏时间超过100MS则主动退出,并回滚整个事务
set local statement_timeout to default;
......
end;
函数级超时例⼦ - statement_timeout不可⽤
例如这个QUERY,我们想让它100毫秒超时。
select count(*) as cnt, id from a where id<$1 group by id;
捕虾笼
将它写到函数中,在函数中设置超时
create or replace function f1(int) returns setof record as $$
declare
begin
set local statement_timeout='100ms';
return query select count(*) as cnt, id from a where id<$1 group by id;
end;
$$ language plpgsql strict ;
调⽤SQL改成这样
select cnt,id from f1(1) as t(cnt int8, id int);
但是这么做实际上是没有效果的,原因是statement_timeout的设计之初是为交互性SQL设计的,在postgres.c中。
镜面果胶
所以需要plpgsql超时,需要通过插件HOOK来实现。
statement_timeout is measured across an entire interactive command, not
individual commands within a function; and the timeout that applies to
an interactive command is determined at its beginning. So the above
doesn't do what you think.
参数级别
1、实例级
修改
2、库级
alter database dbname set parameter=?;
3、⽤户级
alter role rolname set parameter=?;
4、会话级
set parameter=?;
5、事务级
begin;
set local parameter=?;
....
end;
6、函数级
高放废液
alter function fun_name() set parameter=?;
其他超时控制
1、空闲事务超时
idle_in_transaction_session_timeout = 2h
2、锁等待超时
lock_timeout = 1s
3、死锁检测超时间隔
deadlock_timeout = 1s
以上为个⼈经验,希望能给⼤家⼀个参考,也希望⼤家多多⽀持。如有错误或未考虑完全的地⽅,望不吝赐教。

本文发布于:2023-06-30 15:03:49,感谢您对本站的认可!

本文链接:https://patent.en369.cn/patent/2/158480.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:服务器   事务   参数   时间   配置   设置   重启
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 369专利查询检索平台 豫ICP备2021025688号-20 网站地图