PostgreSQL - 在多个分区表上创建索引

PostgreSQL - Creating index on multiple partitioned tables

我正在尝试在多个 (1000) 分区 table 上创建索引。因为我使用的是 Postgres 10.2,所以我必须分别为每个分区执行此操作,必须为此执行 1000 个查询。

我已经想出了如何去做,它确实适用于 table 大小和交易数量非常少的环境。下面是要针对 table 之一执行的查询(将对所有 table 重复执行(user_2、user_3 等)

CREATE INDEX IF NOT EXISTS user_1_idx_location_id 
ON users.user_1 ( user_id, ( user_data->>'locationId') );

其中 user_data 是一个 jsonb 列

此查询不适用于交易量很大的大型 tables - 当我 运行 它一次用于所有 tables 时。抛出错误:

ERROR: SQL State  : 40P01
Error Code : 0
Message    : ERROR: deadlock detected
Detail: Process 77999 waits for ShareLock on relation 1999264 of database 16311; blocked by process 77902.
Process 77902 waits for RowExclusiveLock on relation 1999077 of database 16311; blocked by process 77999

我能够 运行 小批量(每批 25 个)- 有时仍然会遇到问题,但是当我重试一两次时 运行 成功了。批次越小,死锁的可能性越小。

我认为发生这种情况是因为所有用户 table(user_1、user_2 等)都链接到父 table:用户。我不想为索引创建锁定整个 table(因为理论上一次只修改一个 table)。为什么会发生这种情况,有什么办法可以解决这个问题,以确保在没有死锁的情况下创建索引?

这有效:

CREATE INDEX CONCURRENTLY IF NOT EXISTS user_1_idx_location_id 
ON users.user_1 ( user_id, ( user_data->>'locationId') );