不结束数据库事务有什么后果?

时间:2015-11-19 22:08:57

标签: postgresql transactions

我在我的应用程序代码中发现了一个错误,我已经启动了一个事务,但从未提交或执行回滚。连接是定期使用的,只需每10秒左右读取一些数据。在pg_stat_activity表中,其状态报告为"在事务"中空闲,其backend_start时间超过一周。

这对数据库有什么影响?它是否会导致额外的CPU和RAM使用?它会影响其他连接吗?在这种状态下它能持续多久?

我正在使用postgresql 9.1和9.4。

2 个答案:

答案 0 :(得分:12)

由于您只有SELECT,因此影响有限。对于任何写操作来说都是更严重的,其中更改在提交之前对任何其他事务都不可见 - 如果从未提交则丢失。

花费一些内存,永久占用您允许的一个连接(这可能或不重要)。

非常长时间运行的事务的一个更严重的后果:它阻止VACUUM执行它的工作,因为仍然有一个旧事务可以看到旧行。系统将开始膨胀。

特别是,SELECT在所有引用的表上获取ACCESS SHARE锁(所有阻塞最少)。这不会干扰其他DML命令,例如INSERTUPDATEDELETE,但它会阻止DDL命令以及 {{1} } TRUNCATE (包括autovacuum职位)。 See "Table-level Locks" in the manual.

它还可以干扰各种复制解决方案,并且如果长时间保持打开/足够快地刻录足够的XID,则会导致事务ID环绕。关于in the manual on "Routine Vacuuming"的更多信息。

如果其他交易被阻止提交并且已获得自己的锁定,则阻止效果可以蘑菇。等等。

您可以无限期地保持事务处理(几乎) - 直到连接关闭(显然,当服务器重新启动时也会发生这种情况。)
但永远不要让交易开放时间超过需要。

答案 1 :(得分:3)

对系统有两个主要影响。

在这些交易中使用的表格:

  1. 不是vacuumed,这意味着它们没有被“清理”并且他们的统计数据没有更新,这可能会导致糟糕的(=慢的)执行计划
  2. 无法使用ALTER TABLE
  3. 进行更改