UPDATE 语句因锁定而挂起

UPDATE statement hangs because of locks

我 运行 我的 .pgsql 脚本使用 /i blah.pgsql 脚本,然后使用我的 .java 函数调用该 pgsql 来测试它。

不过,我运行之后呢。我意识到它损坏了我的数据,而且我不确定如何调试以及导致数据损坏的原因。我不能 DROP SCHEMA 因为它挂起,所以我必须创建一个新的 SHOW SEARCH_PATH 模式来再次测试它。我已经做了三次,我想避免这个问题。有人可以帮我确定为什么会导致数据损坏吗?谢谢!老实说,这是我遇到的唯一问题,我不明白为什么这会导致一个非常糟糕的损坏数据库。如果您需要更多信息/数据库,请告诉我,以便我编辑和提供更多信息。

创建此文件的目的是获取每次更新的计数。 但似乎更新正在破坏整个数据库文件

这是我的代码

CREATE OR REPLACE function assignDelinquents (theAgent char(6), theCount integer)
RETURNS integer
LANGUAGE plpgsql
AS $$
DECLARE
max_update integer := 0;
counter integer := 0;

BEGIN

  LOOP
    UPDATE Delinquents d
    -- code here 

    counter := counter + 1;

    END LOOP;

   RETURN counter;

END $$;

编辑:pg_stat_activity 结果:https://pastebin.com/46hN1uj9 我是 pgsql 的新手,所以我什么都做不了真的很奇怪。

没有数据库损坏,一切正常。

如果您查看 pg_stat_activity 输出,解释很简单。

  • 在 2018-03-13 23:05:37.362666-07 你开始了

    SELECT * FROM assignDelinquents(,)
    

    仍然是 运行(所以 运行 超过 1.5 小时)。
    这并不奇怪,因为该函数包含一个无限循环。

  • 您于 2018-03-13 23:55:33.097579-07 开始

    DROP SCHEMA Lab4 CASCADE;
    

    它试图在架构中的所有 table 上获得 ACCESS EXCLUSIVE 锁,但显然其中一些 table 已被您的长 运行 使用查询,所以语句被阻塞。

  • 所有试图在已被前一条语句锁定的架构中使用 table 的语句也必须等待。

解决方案是终止长 运行 查询(并修复您的函数)。

SELECT pg_terminate_backend(8838);