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') );
我正在尝试在多个 (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') );