2017-07-06 47 views
1

目前我正试图删除特定数据库表中的一行(s)api_user。然而,删除似乎无限的时间挂起(目前正在运行1800秒,因为我一直在寻找答案)。有问题的行有外键依赖项,但所有这些依赖项都已被删除,并已通过验证。Postgres中的DELETE查询无限期挂起

我正在通过Postico运行我的所有数据库自检(只是另一个数据库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_event是一个具有此表上索引和外键的表。 api_event中的所有依赖行都被删除了。

我已经检查过pg_stat_activity的任何查询可能会同时运行无效,所以我在一个点,我不知道我应该问的下一个问题是什么。任何方向都会很棒!

运行这个EXPLAIN DELETE FROM api_user WHERE organization_id = '<replaced value>';回报对我说:

Delete on api_user (cost=54.94..2903.50 rows=1874 width=6) -> Bitmap Heap Scan on api_user (cost=54.94..2903.50 rows=1874 width=6) Recheck Cond: ((organization_id)::text = '<replaced value>'::text) -> Bitmap Index Scan on api_user_organization_id (cost=0.00..54.47 rows=1874 width=0) Index Cond: ((organization_id)::text = '<replaced value>'::text)

锁监视

你检查它是否在等待一个锁? - a_horse_with_no_name

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

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; 

第一回,我DELETE不是从的pg_classpg_index,并pg_namespace运行,容器3行锁。

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

分辨率

通过更多的问题,researching,一个有趣的花絮出现,不是在子表的外键具有指标。在编写查询以查看哪些外键没有索引之后,我注意到api_event没有索引到它的api_user外键。现在api_event是一个humongous表。

上创建索引api_event解决了这个问题。

CREATE INDEX CONCURRENTLY user_id_to_events ON api_event(user_id); 
+0

这张桌子有多大? 'EXPLAIN'告诉你什么? –

+0

你有没有检查它是否在等待锁? –

+0

@TimBiegeleisen我编辑了原帖! –

回答

0

我不确定(而且无法评论),但我认为您在删除后遇到重新索引或真空。