简体   繁体   English

Postgres 中的 DELETE 查询无限期挂起

[英]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_classpg_indexpg_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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM