我们有一个包含主键索引膨胀的大表。我们不断地对该表归档旧记录。
我们通过同时重建索引并删除旧索引的方式重新索引其他列,以避免干扰生产流量。但是对于主键来说,这是不可能的,因为依赖它的外键太多,至少根据我们所尝试的。
如何安全地重新索引主键而不阻塞对表上的DML语句?
我们有一个包含主键索引膨胀的大表。我们不断地对该表归档旧记录。
我们通过同时重建索引并删除旧索引的方式重新索引其他列,以避免干扰生产流量。但是对于主键来说,这是不可能的,因为依赖它的外键太多,至少根据我们所尝试的。
如何安全地重新索引主键而不阻塞对表上的DML语句?
REINDEX CONCURRENTLY
似乎也可以使用。我在我的数据库上尝试了一下,没有收到任何错误。
REINDEX INDEX CONCURRENTLY <indexname>;
我认为它可能类似于@jlandercy在他的答案中描述的内容。在重建索引时,我看到了一个后缀为_ccnew
的索引,并且现有的索引也完好无损。最终,我猜测在删除旧索引后,该索引被重命名为原始索引,并最终在我的表上看到了唯一的主索引。
我正在使用postgresv12.7
。
CONCURRENTLY
选项自 V12 版本开始提供,早期版本没有此功能。 - EAmezpg_repack -t table_name --only-indexes
只需使用索引名称将其重新索引即可,像其他索引一样:reindex
REINDEX INDEX <indexname>;
让我们创建一个带有主键约束且同时也是索引的表:
Original Answer翻译成:"最初的回答"
CREATE TABLE test(
Id BIGSERIAL PRIMARY KEY
);
Original Answer
SELECT conname FROM pg_constraint WHERE conname LIKE 'test%';
-- "test_pkey"
Having the name of the index, we can reindex it:
REINDEX INDEX test_pkey;
同时,你也可以在创建时固定约束名称:
CREATE TABLE test(
Id BIGSERIAL NOT NULL
);
ALTER TABLE test ADD CONSTRAINT myconstraint PRIMARY KEY(Id);
a_horse_with_no_name
建议的方式,同时创建唯一索引。最初的回答。-- Ensure Uniqueness while recreating the Primary Key:
CREATE UNIQUE INDEX CONCURRENTLY tempindex ON test USING btree(Id);
-- Drop PK:
ALTER TABLE test DROP CONSTRAINT myconstraint;
-- Recreate PK:
ALTER TABLE test ADD CONSTRAINT myconstraint PRIMARY KEY(Id);
-- Drop redundant Index:
DROP INDEX tempindex;
检查索引是否存在:
SELECT * FROM pg_index WHERE indexrelid::regclass = 'tempindex'::regclass
ALTER TABLE test DROP CONSTRAINT myconstraint, ADD CONSTRAINT myconstraint PRIMARY KEY(Id) using index tempindex;
。这是事务性的,不需要手动drop index
。 - user158037
reindex
函数有什么问题吗? - user330315