解决PostgreSQL 执行超时的情况

 更新时间:2021年01月16日 15:48:10   作者:朝雨忆轻尘  
这篇文章主要介绍了解决PostgreSQL 执行超时的情况,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

使用背景

最近在使用PostgreSQL的时候,在执行一些数据库事务的时候,先后出现了statement timetout 和idle-in-transaction timeout的问题,导致数据库操作失败。

经研究查找,PostgreSQL有关于SQL语句执行超时和事务执行超时的相关配置,而默认超时时间是10000毫秒,即10秒钟的时间,这样会导致执行时间稍长的任务执行失败。可以通过修改PostgreSQL服务器配置文件的方式修改默认配置。

参数说明

statement_timeout
statement_timeout 在 postgresql 被用来控制语句执行时长,单位是ms。
$ vi postgresql.conf 
#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。

$ vi postgresql.conf 
#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 "postgresql.conf"
vi /var/lib/pgsql/9.6/data/postgresql.conf

修改参数

进入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

重启服务器,等待其停止和重启:

$ 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来实现。

https://www.postgresql.org/message-id/flat/200702201200.53535.xzilla%40users.sourceforge.net#200702201200.53535.xzilla@users.sourceforge.net

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、实例级

修改

postgresql.conf 

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

https://www.postgresql.org/docs/9.4/static/runtime-config-client.html

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。如有错误或未考虑完全的地方,望不吝赐教。

相关文章

  • Postgresql和mysql的区别及说明

    Postgresql和mysql的区别及说明

    这篇文章主要介绍了Postgresql和mysql的区别及说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-11-11
  • PostgreSQL游标与索引选择实例详细介绍

    PostgreSQL游标与索引选择实例详细介绍

    这篇文章主要介绍了PostgreSQL游标与索引选择优化案例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧
    2022-09-09
  • PostgreSQL数据类型格式化函数操作

    PostgreSQL数据类型格式化函数操作

    这篇文章主要介绍了PostgreSQL数据类型格式化函数操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-12-12
  • postgresql查询每个月的最后一天日期并对未查到的日期结果补0(操作示例)

    postgresql查询每个月的最后一天日期并对未查到的日期结果补0(操作示例)

    这篇文章主要介绍了postgresql查询每个月的最后一天日期,并对未查到的日期结果补0,pgsql需要使用函数使用date_trunc()函数找到指定月第一天,然后对该日期先加一个月在减一个月就能得到你传给的日期的最后一天日期,感兴趣的朋友跟随小编一起看看吧
    2023-10-10
  • PostgreSQL 实现列转行问题

    PostgreSQL 实现列转行问题

    这篇文章主要介绍了PostgreSQL 实现列转行问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-01-01
  • PostgreSQL如何查询表大小(单独查询和批量查询)

    PostgreSQL如何查询表大小(单独查询和批量查询)

    PostgreSQL提供了多个系统管理函数来查看表,索引表空间及数据库的大小,这篇文章主要给大家介绍了关于PostgreSQL如何查询表大小的相关资料,文中介绍的方法包括单独查询和批量查询,需要的朋友可以参考下
    2024-02-02
  • Postgresql开启远程访问的步骤全纪录

    Postgresql开启远程访问的步骤全纪录

    postgre一般默认为本地连接,不支持远程访问,所以如果要开启远程访问,需要更改安装文件的配置。下面这篇文章主要给大家介绍了关于Postgresql开启远程访问的相关资料,需要的朋友可以参考借鉴,下面来一起看看吧。
    2018-03-03
  • postgresql 导出建表语句的命令操作

    postgresql 导出建表语句的命令操作

    这篇文章主要介绍了postgresql 导出建表语句的命令操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-12-12
  • 详解PostgreSQL 实现定时任务的 4 种方法

    详解PostgreSQL 实现定时任务的 4 种方法

    这篇文章主要介绍了PostgreSQL 实现定时任务的 4 种方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-02-02
  • Ubuntu中卸载Postgresql出错的解决方法

    Ubuntu中卸载Postgresql出错的解决方法

    这篇文章主要给大家介绍了关于在Ubuntu中卸载Postgresql出错的解决方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧。
    2017-09-09

最新评论