Database Postgres中的删除查询无限期挂起

Database Postgres中的删除查询无限期挂起,database,postgresql,Database,Postgresql,当前我正在尝试删除特定数据库表中的一行api\u user。然而,删除挂起的时间似乎是无限的(我一直在寻找答案,目前运行了1800秒)。有问题的行有外键依赖项,但所有这些依赖项都已被删除,这已得到验证 我正在通过Postco(只是另一个数据库GUI客户端)运行我的所有数据库内省,因此当我取消查询时,我会收到此错误消息 ERROR: canceling statement due to user request CONTEXT: SQL statement "SELECT 1 FROM ONLY

当前我正在尝试删除特定数据库表中的一行api\u user。然而,删除挂起的时间似乎是无限的(我一直在寻找答案,目前运行了1800秒)。有问题的行有外键依赖项,但所有这些依赖项都已被删除,这已得到验证

我正在通过Postco(只是另一个数据库GUI客户端)运行我的所有数据库内省,因此当我取消查询时,我会收到此错误消息

ERROR: canceling statement due to user request
CONTEXT: SQL statement "SELECT 1 FROM ONLY "public"."api_event" x WHERE $1::pg_catalog.text OPERATOR(pg_catalog.= ) "user_id"::pg_catalog.text FOR KEY SHARE OF x"
有一些索引引用了此表中的行。api_事件是一个在此表上具有索引和外键的表。已删除api_事件中的所有依赖行

我已经检查了pg_stat_活动,查看是否有可能同时运行但没有结果的查询,因此我不确定下一个问题是什么。任何方向都很好

运行
EXPLAIN DELETE FROM api_user,其中组织id=“”将此返回给我:

api用户删除(成本=54.94..2903.50行=1874宽度=6)
->api_用户上的位图堆扫描(成本=54.94..2903.50行=1874宽度=6)
重新检查条件:((组织id)::text='':text)
->api用户组织id上的位图索引扫描(成本=0.00..54.47行=1874宽度=0)
索引条件:((组织id)::text='':text)

锁监控


你检查过它是否在等锁吗?-没有名字的马

根据请求,我搜索了数据库上的锁。我使用了这个查询:

 select t.relname,
        l.locktype,
        page,
        virtualtransaction,
        pid,
        mode,
        granted 
 from pg_locks l, 
      pg_stat_all_tables t 
 where l.relation=t.relid 
 order by relation asc;
第一次返回,my DELETE未运行,包含来自pg_类pg_索引pg_命名空间的3行锁

第二次返回,my DELETE正在运行,包含21行锁。所有这些都是以前删除的一组行中的relname,这些行具有外键或该行的索引

解决之路

通过更多的问题和讨论,出现了一个有趣的小道消息,即并非子表上的所有外键都有索引。在编写了一个查询以查看哪些外键没有索引之后,我注意到api\u事件没有其api\u用户外键的索引。现在,api_事件是一个庞大的表

在api_事件上创建索引解决了该问题

CREATE INDEX CONCURRENTLY user_id_to_events ON api_event(user_id);

我不确定(也不能发表评论),但我认为你正在经历一个严重的重新指数化或删除后的真空

创建索引实际上对于慢速删除查询很有用。 当您使用“解释-分析从xx删除”运行删除查询,并因太慢而取消时,将显示:

ERROR:  canceling statement due to user request
CONTEXT:  SQL statement "DELETE FROM ONLY "public"."AAAA" WHERE $1 OPERATOR(pg_catalog.=) "BBBB""
同时运行
创建AAAA(BBBB)上索引的名称\u


将解决此问题

此表有多大?
EXPLAIN
向你展示了什么?你检查过它是否在等待锁定吗?@TimBiegeleisen我编辑了原始帖子@我在检查锁的结果中添加了一匹没有名字的马@Dariuscalie“删除时挂起”的答案是因为应用程序仍然访问要删除的表。确保您要删除的表没有人访问它。因此,PostgreSQL可以优雅地删除表。