【问题标题】:Pg_repack table without unique key没有唯一键的 Pg_repack 表
【发布时间】:2020-03-18 22:45:52
【问题描述】:

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

【问题讨论】:

    标签: postgresql unique-key


    【解决方案1】:

    总会有性能影响,您的目标是使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;
    

    希望下次你知道的更好,以后再也不会创建没有主键的表了。

    【讨论】:

    • 如果您使用 postgres 12 及更高版本,您可以添加:“alter table x add check (id not null) not valid; alter table x validate constraint x_id_check; alter table x add primary key using index x_id_idx ;"。如果该列上已经没有空约束检查,则 Postgres 12 及更高版本将在设置非空列时跳过全表扫描。因此,添加主键将是最小锁定。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-24
    • 1970-01-01
    • 2019-10-31
    • 1970-01-01
    • 2017-07-22
    相关资源
    最近更新 更多