首页 > 解决方案 > 没有唯一键的 Pg_repack 表

问题描述

我有以下问题:我有一张桌子,当然是在产品上……有时在我们遇到 INT pk 的限制之前,我们只需将其修改为默认值 -1。现在我想在它上面运行 pg_repack ,但这需要没有 NULL 和唯一的键。你有这方面的经验吗?我的选择: 1. 真空满。不能,因为影响。2.添加一些额外的独特列,可能需要一些时间和影响。也可以破坏 select * 查询。3.添加默认值的列,然后用序列更新并标记为唯一。以前从未尝试过。AWS RDS。

标签: postgresqlunique-key

解决方案


总会有性能影响,您的目标是使ACCESS EXCLUSIVE锁尽可能短。

所以

  • 添加bigint没有默认值的列

  • 创建一个序列OWNED BY新列

  • 用于使用ALTER TABLE序列为列设置默认值

  • 从序列中更新新列中的 NULL 值

    您应该分批执行此操作,以避免一次锁定太多行。

  • 在新列上创建唯一索引CONCURRENTLY

  • 使用新索引添加唯一约束

这不会给你一个主键,因为你仍然缺少NOT NULL约束。NOT NULL如果不扫描整个表,就无法设置列,这将保持ACCESS EXCLUSIVE更长的锁定时间。但是,如果您需要真正的主键,则无法避免。

这是我在 SQL 中使用示例表的过程:

ALTER TABLE x ADD id bigint;

CREATE SEQUENCE x_id_seq OWNED BY x.id;

ALTER TABLE x ALTER id SET DEFAULT nextval('x_id_seq');

UPDATE x SET id = nextval('x_id_seq')
WHERE id IS NULL
  AND somecol BETWEEN 1 AND 10000;
UPDATE x SET id = nextval('x_id_seq')
WHERE id IS NULL
  AND somecol BETWEEN 10001 AND 20000;
...

CREATE UNIQUE INDEX CONCURRENTLY x_id_idx ON x(id);

ALTER TABLE x ADD UNIQUE USING INDEX x_id_idx;

我希望下次您知道得更好,并且您永远不会再创建没有主键的表。


推荐阅读