[英]DELETE query in Postgres hangs indefinitely
Currently I am trying to delete a row(s) in a particular database table api_user .目前我正在尝试删除特定数据库表api_user中的一行。 Yet deleting hangs for seemingly infinite time ( currently been running for 1800 seconds as I've been looking for answers ) .
然而,删除挂起的时间看似无限长(目前已运行 1800 秒,因为我一直在寻找答案) 。 The row in question had foreign key dependents, yet all of those dependents were deleted already, thats been verified.
有问题的行有外键依赖项,但所有这些依赖项都已被删除,这已经过验证。
I'm running all of my database introspection through Postico ( just another database GUI client ) So When i cancel the query i receive this error message.我正在通过 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"
There are indexes that referenced the rows in this table.有索引引用了该表中的行。 api_event is one table that had indexes on and foreign keys to this table.
api_event是一个表,该表具有该表的索引和外键。 All of the dependent rows from api_event were deleted.
api_event 中的所有相关行都已删除。
I've checked pg_stat_activity for any queries that could be running concurrently to no avail, and so I'm at a point where I'm not sure what the next question I should be asking is.我已经检查了 pg_stat_activity 是否有任何可能同时运行但无济于事的查询,所以我不确定我应该问的下一个问题是什么。 Any direction would be great!
任何方向都会很棒!
Running EXPLAIN DELETE FROM api_user WHERE organization_id = '<replaced value>';
运行
EXPLAIN DELETE FROM api_user WHERE organization_id = '<replaced value>';
returns this to me:把这个还给我:
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)
Lock Monitoring锁定监控
Did you check if it's waiting for a lock?
你有没有检查它是否在等待锁定? – a_horse_with_no_name
– a_horse_with_no_name
As per request I searched the locks on my database.根据要求,我搜索了数据库中的锁。 I used this query:
我使用了这个查询:
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;
The first return, my DELETE was not running, container 3 rows of locks from pg_class , pg_index , and pg_namespace .第一次返回,我的 DELETE 没有运行,容器 3 行来自pg_class 、 pg_index和pg_namespace的锁。
The second return, my DELETE was running, contained 21 rows of locks.第二次返回,我的 DELETE 正在运行,包含 21 行锁。 All of which were of a relname from a previously deleted set of rows that had either a foreign key or an index with this row.
所有这些都是来自先前删除的一组行的 relname,这些行具有外键或该行的索引。
Road to Resolution解决之路
Through more questions and researching , an interesting tidbit arose that not all foreign keys on child tables have indexes .通过更多的问题和研究,出现了一个有趣的花絮,即并非所有子表上的外键都有索引。 After composing a query to see what foreign keys don't have indexes I noted that api_event did not have an index to its api_user foreign key.
在编写查询以查看哪些外键没有索引后,我注意到api_event没有对其api_user外键的索引。 Now api_event is a humongous table.
现在api_event是一个巨大的表。
Creating an index on api_event solved the issue.在api_event上创建索引解决了这个问题。
CREATE INDEX CONCURRENTLY user_id_to_events ON api_event(user_id);
我不确定(也无法发表评论),但我认为删除后您正在经历大量重新索引或清理工作。
Create index is actually useful for slow delete query. 创建索引实际上对于缓慢删除查询很有用。 When you run DELETE query with "explain analyze delete from xx" ,and cancel it for too slow ,it will shows:
当您使用“解释分析从xx删除”运行DELETE查询,并以太慢的速度将其取消时,它将显示:
ERROR: canceling statement due to user request
CONTEXT: SQL statement "DELETE FROM ONLY "public"."AAAA" WHERE $1 OPERATOR(pg_catalog.=) "BBBB""
run CREATE INDEX CONCURRENTLY NAME_OF_INDEX ON AAAA(BBBB)
在
CREATE INDEX CONCURRENTLY NAME_OF_INDEX ON AAAA(BBBB)
运行CREATE INDEX CONCURRENTLY NAME_OF_INDEX ON AAAA(BBBB)
will fix this problem 将解决这个问题
Not a very useful answer, but it might help someone.不是一个非常有用的答案,但它可能会对某人有所帮助。 I experienced the same issue after doing excessive deletions on the table.
在表上进行过多删除后,我遇到了同样的问题。 I was experimenting with different delete queries and trying to find out which one is the fastest.
我正在尝试不同的删除查询并试图找出哪个是最快的。 I was also cancelling queries before they finished.
我也在他们完成之前取消了查询。 I could not find the underlying reason, but what fixed the problem for me is
我找不到根本原因,但对我来说解决问题的是
My DB was hosted on google cloud with backup support.我的数据库托管在具有备份支持的谷歌云上。 So, I restored a backup from a few days ago, and the problem was gone.
所以,我恢复了几天前的备份,问题就解决了。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.