简体   繁体   English

为什么我的“CREATE INDEX CONCURRENTLY ..”命令被“SELECT FROM”查询阻止? (Postgres 9.6)

[英]Why is my "CREATE INDEX CONCURRENTLY .." command blocked by a "SELECT FROM" query? (Postgres 9.6)

I was running a migration to create an index, but the migration was blocked by another query.我正在运行迁移以创建索引,但迁移被另一个查询阻止。 I resolved the problem after discovering that there was another query blocking my migrations;在发现有另一个查询阻止了我的迁移后,我解决了这个问题; and after cancelling the blocking query, I was able to successfully run the migration.取消阻塞查询后,我能够成功运行迁移。

(My server is using Postgres 9.6 on Linux) (我的服务器在 Linux 上使用 Postgres 9.6)

Here is how I discovered that my migration was blocked:以下是我发现我的迁移被阻止的方式:

SELECT
    activity.pid,
    activity.usename,
    activity.query,
    blocking.pid AS blocking_id,
    blocking.query AS blocking_query
FROM pg_stat_activity AS activity
JOIN pg_stat_activity AS blocking ON blocking.pid = ANY(pg_blocking_pids(activity.pid));

which returned the following result:返回以下结果:

| pid | usename | query                                                                           | blocking_id | blocking_query                                                              |
|-----+---------+---------------------------------------------------------------------------------+-------------+-----------------------------------------------------------------------------|
| 123 | my_user | CREATE  INDEX CONCURRENTLY "idx_orders_on_widget_id" ON "orders"  ("widget_id") | 456         | SELECT  "customers".* FROM "customers" WHERE "customers"."id" = $1 LIMIT $2 |

How is it possible that my migration (the CREATE INDEX CONCURRENTLY .. query) was being blocked by the SELECT .. FROM .. query?我的迁移( CREATE INDEX CONCURRENTLY ..查询)怎么可能被SELECT .. FROM ..查询阻止? Even if the process running the blocking query was in a zombie state, I don't understand how my index creation query can be blocked by a "SELECT .. FROM .." query.即使运行阻塞查询的进程处于僵死状态,我也不明白我的索引创建查询如何被“SELECT .. FROM ..”查询阻塞。

Can anyone offer insights about how this is possible?任何人都可以提供有关这是如何可能的见解吗?

If it helps, here is my schema (simplified for this question):如果有帮助,这是我的架构(针对此问题进行了简化):

Orders订单

id

widget_id

customer_id (FK to Customers ) customer_id (FK 到Customers

Customers顾客

id

company_id (FK to Companies ) company_id (FK 到Companies

Companies公司

id

Some additional notes:一些补充说明:

  • I discovered that the index was blocked about ~8 hours after I ran the migration.我发现在运行迁移大约 8 小时后索引被阻止了。
  • After killing the blocking query, I dropped the idx_orders_on_widget_id index and re-ran the migration to re-create the index.杀死阻塞查询后,我删除了idx_orders_on_widget_id索引并重新运行迁移以重新创建索引。
  • After re-running the migration a second time, the index creation was finished in ~10 mins第二次重新运行迁移后,索引创建在大约 10 分钟内完成
  • The server is running on Linux with Postgres 9.6服务器在 Linux 上运行,使用 Postgres 9.6

The documentation says:文档说:

PostgreSQL supports building indexes without locking out writes. PostgreSQL 支持在不锁定写入的情况下构建索引。 This method is invoked by specifying the CONCURRENTLY option of CREATE INDEX .通过指定CREATE INDEXCONCURRENTLY选项来调用此方法。 When this option is used, PostgreSQL must perform two scans of the table, and in addition it must wait for all existing transactions that could potentially modify or use the index to terminate .使用此选项时,PostgreSQL 必须对表执行两次扫描,此外它还必须等待所有可能修改或使用索引的现有事务终止

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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