Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Postgresql 不结束数据库事务的后果是什么?_Postgresql_Transactions - Fatal编程技术网

Postgresql 不结束数据库事务的后果是什么?

Postgresql 不结束数据库事务的后果是什么?,postgresql,transactions,Postgresql,Transactions,我在应用程序代码中发现了一个bug,我启动了一个事务,但从未提交或执行回滚。连接是定期使用的,只是每隔10秒左右读取一些数据。在pg_stat_activity表中,其状态报告为“事务中空闲”,其backend_start时间超过一周 这对数据库有什么影响?它是否会导致额外的CPU和RAM使用?它会影响其他连接吗?这种状态能持续多久 我使用的是postgresql 9.1和9.4。对系统有两个主要影响 已在这些交易中使用的表: 不是,这意味着它们没有被“清理”,并且它们的统计数据没有更新,这可能

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

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


我使用的是postgresql 9.1和9.4。

对系统有两个主要影响

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

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

  • 由于您只选择了,因此影响是有限的。对于任何写入操作来说,情况更为严重,在提交之前,更改对任何其他事务都不可见,如果从未提交,则更改将丢失

    它确实花费了一些RAM,并且永久占用了您允许的一个连接(这可能很重要,也可能不重要)

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

    特别是,
    SELECT
    在所有引用的表上获取
    访问共享
    锁(所有表中阻塞最少的一个)。这不会干扰其他DML命令,如
    插入
    更新
    删除
    ,但它将阻止DDL命令以及
    截断
    真空
    (包括自动真空作业)

    它还可能干扰各种复制解决方案,并从长远来看,如果它保持足够长的开放时间/您燃烧足够快的XID,则会导致事务ID被包围。更多关于这个

    如果其他事务被阻止提交,并且这些事务已经获得了自己的锁,则阻止效果会迅速增加。等等

    您可以无限期(几乎)保持事务打开,直到连接关闭(显然,服务器重新启动时也会发生这种情况。)

    但不要让交易的开放时间超过需要。

    影响:1。您的数据对其他事务不可见2。如果您最终没有提交,您将丢失数据。@zerkms我更感兴趣的是对服务器的处理影响:我意识到所做的任何更改对其他连接都不可见(尽管在这种情况下,它只是读取数据,从不修改任何内容)丢失数据最终不是一个问题,因为您可以始终使用保存点。它只是阻止事务中使用的表的真空,还是阻止所有表的真空?实际上,
    VACUUM
    可以处理一个被虚拟xid锁定为
    访问共享的表。不过,它无法截断它以释放回操作系统的空间。如果事务可序列化
    ,或具有当前正在运行的语句,则无法删除由并发更新/删除创建的死行。你自己试试看。创建具有虚拟行的表。启动xact并从表中选择以锁定它。启动另一个xact并删除一半的行,但不要提交<代码>从另一个会话中清除冗余。它将删除死行。
    SERIALIZABLE
    REPEATABLE READ
    xacts阻止真空删除死行。它只是一个
    读取提交的
    xact,没有活动的快照,使真空继续进行。其他一些事情,比如带HOLD的
    游标、准备好的XACT等等。检查
    pg\u stat\u语句中的
    backend\u xmin
    以查看后端是否阻止真空。仅在9.4及更新版本中。1@CraigRinger vaccum不一定只对该事务中的表起作用,它会对所有表起作用,因为当有一个正在运行的事务时,之后创建的死元组不会被所有表的真空清除,因为事务id是全局生成的,它检查的事务id小于最早事务的事务id