目前我正在尝试删除特定数据库表API_user中的一行。但删除挂起的时间似乎是无限的 (目前运行了1800秒,因为我一直在寻找答案)。问题所在的行有外键依赖项,但所有这些依赖项都已删除,这是经过验证的。
我正在通过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_class、pg_index和pg_namespace的3行锁。
第二个返回值,我的DELETE正在运行,包含21行锁,所有这些锁都是以前删除的一组行的relname,这些行与此行有外键或索引。
通往解决之路
通过更多的问题和researching,一个有趣的小插曲出现了,并不是所有的子表上的外键都有索引。在编写了一个查询以查看哪些外键没有索引之后,我注意到API_event没有到它的api_user外键的索引。现在api_event是一个巨大的表。
在API_event上创建索引解决了这个问题。
CREATE INDEX CONCURRENTLY user_id_to_events ON api_event(user_id);
3条答案
按热度按时间xzv2uavs1#
创建索引实际上对慢删除查询很有用,当你运行带有"解释分析从xx删除"的DELETE查询,并因太慢而取消时,它会显示:
运行
CREATE INDEX CONCURRENTLY NAME_OF_INDEX ON AAAA(BBBB)
我将解决此问题
czq61nw12#
我不确定(也不能发表评论),但我认为你正在经历一个沉重的重新指数化或真空后,您删除。
e5njpo683#
这不是一个很有用的答案,但可能会对某些人有所帮助。我在对表执行过多删除操作后遇到了同样的问题。我尝试了不同的删除查询,并试图找出哪一个最快。我还在查询完成之前取消了查询。我找不到根本原因,但解决问题的方法是
我的DB托管在Google Cloud上,有备份支持。所以,我从几天前恢复了一个备份,问题就没有了。