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

wol*_*tle 7 postgresql transactions

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

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

我正在使用postgresql 9.1和9.4.

Erw*_*ter 13

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

它确实占用了一些RAM,并永久占用了您允许的连接之一(可能或不重要).

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

特别是,在所有引用的表上SELECT获取ACCESS SHARE锁(最少阻塞).这不会干扰其他DML命令INSERT,UPDATE或者DELETE,但它会阻止DDL命令以及TRUNCATEVACUUM(包括autovacuum作业).请参阅手册中的"表级锁".

它还可以干扰各种复制解决方案,并且如果它保持打开足够长时间/你足够快地刻录足够的XID,则可以长期导致 事务ID环绕.更多关于"常规吸尘"手册中的内容.

阻断效果如果其他交易都犯堵塞和那些具有自己的锁.等等.

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

  • 实际上,`VACUUM`可以处理由虚拟xid锁定为"ACCESS SHARE"的表.但它不能截断它以释放空间回到操作系统.如果事务是"SERIALIZABLE",或者具有当前正在运行的语句,则它不能删除由并发更新/删除创建的死行.亲自尝试一下.创建一个包含虚拟行的表.启动一个xact并从表中选择以锁定它.启动另一个xact并删除一半的行但尚未提交.来自另一场会议的"VACUUM VERBOSE".它会删除死行. (2认同)