0

我正在运行迁移以创建索引,但迁移被另一个查询阻止。在发现有另一个查询阻止了我的迁移后,我解决了这个问题;取消阻塞查询后,我能够成功运行迁移。

(我的服务器在 Linux 上使用 Postgres 9.6)

以下是我发现我的迁移被阻止的方式:

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));

返回以下结果:

| 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 |

我的迁移(查询)怎么可能CREATE INDEX CONCURRENTLY ..被查询阻止SELECT .. FROM ..?即使运行阻塞查询的进程处于僵尸状态,我也不明白我的索引创建查询如何被“SELECT .. FROM ..”查询阻塞。

任何人都可以提供有关这如何可能的见解吗?

如果有帮助,这是我的架构(针对这个问题进行了简化):

订单

id

widget_id

customer_id(FK 至Customers)

顾客

id

company_id(FK 至Companies)

公司

id

一些附加说明:

  • 我发现索引在我运行迁移大约 8 小时后被阻止。
  • 杀死阻塞查询后,我删除了idx_orders_on_widget_id索引并重新运行迁移以重新创建索引。
  • 第二次重新运行迁移后,索引创建在大约 10 分钟内完成
  • 服务器在 Linux 上运行 Postgres 9.6
4

1 回答 1

2

文档说:

PostgreSQL 支持在不锁定写入的情况下构建索引。CONCURRENTLY通过指定 的选项调用此方法CREATE INDEX。使用此选项时,PostgreSQL 必须对表执行两次扫描,此外,它必须等待所有可能修改或使用索引的现有事务终止

于 2020-09-28T06:11:18.473 回答