当连接超时时,Postgres行锁会发生什么?

7
我在查看Postgres Docs,但它似乎没有提及连接超时或事务未关闭时会发生什么情况。使用这个锁是安全的吗?如果一个来自 Web 服务器的线程获得了行级锁并超时了,会发生什么?如果连接已中断,那么锁将被释放吗?如果没有呢?
文档中唯一找到的保证是使用statement_timeout,但我认为后者会影响读取和写入,这不是预期的效果。

statement_timeout (integer)

任何花费指定毫秒数以上时间的语句都将被中止,从命令从客户端到达服务器的时间开始计算。如果log_min_error_statement设置为ERROR或更低级别,则超时的语句也将被记录在日志中。值为零(默认值)表示关闭此功能。

不建议在postgresql.conf中设置statement_timeout,因为它会影响所有会话。

1个回答

10

当一个带有打开事务的连接超时时,该事务会被回滚(中止)。这将释放所有行锁。

连接超时不是PostgreSQL自身完成的,而是由操作系统TCP堆栈完成的。TCP keepalive对此很有用。

请注意,statement_timeout将标记事务已中止,但不会回滚并释放其锁定。您仍然需要执行ROLLBACK。在PostgreSQL中没有“事务超时”,也没有任何数据库服务器级别的连接超时。

如果您想限制锁定行的持续时间,您可能需要监视pg_lockspg_stat_activity。特别关注pg_stat_activitywaiting列和pg_locksgranted列。请参见https://wiki.postgresql.org/wiki/Lock_Monitoring


感谢您的回复。是什么决定了连接超时(例如,如果Web服务器OOM并且在磁盘上进行大量分页以一种使整个进程停滞而不会崩溃的方式)?是否有一种方法可以在事务开始时设置事务超时限制? - user3467349
没有连接超时或空闲事务超时,只有语句超时。唯一的连接超时是在更低的级别,如果TCP连接断开。除非启用了keepalives,否则需要很长时间,即使使用keepalives也不快。这是假设对等主机完全无响应; 如果它以TCP RST响应,它会迅速中断。如果Web服务器处于挣扎/停滞状态,则数据库连接可能会保持打开和空闲。为什么?你试图解决什么潜在的问题? - Craig Ringer
我只是在寻找某些保证,即可能在获取行锁后开始停顿的某个服务器只能阻塞其他服务器有限(可预测)的时间。最好的方法是拆分读写池并在连接级别上设置语句超时吗? - user3467349
3
语言:简体中文超时语句不会回滚查询并释放锁定。你仍然需要执行回滚操作,它不会达到你想要的效果。我觉得你是在尝试限制持有行级锁的事务时间。如果是这样,我建议通过使用 cron 作业来监视 pg_lockspg_stat_activity,查找在锁定上阻止其他事务超过 'n' 秒的事务并终止它们。请参见 https://wiki.postgresql.org/wiki/Lock_Monitoring - Craig Ringer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接