在解决问题前,先来了解一下数据库连接的几种状态。
pg_stat_activity 是一张postgresql的系统视图,它的每一行都表示一个系统进程,显示与当前会话的活动进程的一些信息,比如当前会话的状态和查询等。它的state字段表示当前进程的状态,一共有六种: 1、Active(活动): 进程正在执行某个语句 2、Idle(空闲): 进程正在等待客户端的指令 3、idle in transaction(事务空闲):进程在处理事务的过程中,但当前没有执行任何语句 4、idle in transaction (aborted)(事务空闲-退出):除了事务中声明一个错误外,其余情况与idle in transaction相同 5、fastpath function call(快速通道函数调用): 后台正在执行某个快速通道函数 6、Disabled(禁用): 报告状态被禁用
一、实际测试一个连接常见状态: 开启另一个连接查询当前数据库的所有连接状态。 在创建的连接不执行任何语句的情况下,连接状态为:idle 二、以查询连接状态的会话为例,正在执行某个语句的连接状态为:active 三、尝试开启一个事务: 这时开启事务的连接状态变成了:idle in transaction 执行一些sql语句 查看连接状态,发现依然为idle in transaction 四、提交事务 状态重新变回idle 五、使用end,报警告,提示没有正在进行的事务(印象中Mysql是以end来结束一个事务的,所以试了一下) 重新开启一个事务,执行一条插入语句。直接执行end;发现事务默认被提交 六、重新开启一个事务: 如果不做提交操作或者没有断开连接,那么连接状态就会一直处于idle in transaction。 Postgresql在9.6版本提供了idle_in_transaction_session_timeout 参数,用于释放一直处于idle in transaction状态下的连接。 尝试在postgresql.conf 文件中添加idle_in_transaction_session_timeout参数控制,参数单位为毫秒idle_in_transaction_session_timeout=30000 七、再次开启一个事务,执行一条查询语句,并查看该连接的状态 过了30秒后,pid为17197的连接被断开: 八、重新创建连接,不做任何操作(使连接处于空闲状态): 等待一段时间后,连接依然存在。 测试结果显示,增加了idle_in_transaction_session_timeout参数后,数据库会自动断开在事务空闲状态下的连接,而空闲状态下的连接不受影响。 九、尝试写一个一直在active状态下的sql(sql具体内容不要在意) 过了一段时间后,发现状态任然为 avtive 也就是说idle_in_transaction_session_timeout参数不会影响在active状态下的连接。