【问题标题】:How to add a not null column to postgresql table without doubling its size on disk如何在不将磁盘大小加倍的情况下向 postgresql 表添加非空列
【发布时间】:2010-01-18 16:29:42
【问题描述】:

有没有办法在不将磁盘大小加倍的情况下向 Postgresql 表添加非空类型列?例如,如果我有一个定义了一些列的表,并且我想添加一个列,我会执行以下操作:

alter table my_table add new_column int  
update table my_table set new_column = 0 
alter table my_table alter column new_column set not null

由于 Postgresql 的工作方式,这实际上使为表分配的空间增加了一倍。更新正在创建新的元组,这些元组将在此事务完成并且真空完成其工作后被标记为重用。如果表的大小很大(即几百万行)但增长非常缓慢或大小几乎恒定,则这些行将永远不会被重用,并且只有“真空满”或完整的数据库备份和恢复会回收磁盘上的空间。有没有办法自动添加具有某些默认值但没有这种行为的列?例如,如果有一种方法可以锁定表并进行更新,那么在这种情况下就不需要 MVCC。

【问题讨论】:

    标签: postgresql admin


    【解决方案1】:

    分步进行:

    1. alter table 添加新列
    2. 更改表为列添加默认值
    3. 更新,但不是带有 1 个更新语句的整个表,而是像 10000 个单独的更新一样发出它,每个更新都在自己的事务中
    4. 每隔几百次更新运行一次清理,或者更好 - 自动清理
    5. alter table set not null

    【讨论】:

    • 听起来不错,我认为这将解决我的问题,尽管它会使升级脚本比原来的 'alter table / update/alter table' 3 行更复杂一些。无论如何,Tnx。
    【解决方案2】:

    如果表很大(即很少 百万行)但增长非常缓慢 或者在大小上几乎是恒定的 行将永远不会被重用,并且只有一个 'vacuum full' 或完整的数据库 备份和恢复将回收空间 在磁盘上。

    这似乎很可疑。我想知道您的可用空间图是否不够大——当这种情况发生时,postgres 开始丢失对已删除行的跟踪,并且无法回收它们,除非真空已满。如果您正在运行 Postgres

    max_fsm_pages 在 Postgresql 8.4 中消失了。如果你运行的是 8.4,那没关系。

    【讨论】:

    • 是的,我们正在使用 postgres
    猜你喜欢
    • 2015-12-11
    • 1970-01-01
    • 1970-01-01
    • 2020-06-08
    • 2017-05-11
    • 1970-01-01
    • 2015-11-27
    • 1970-01-01
    • 2019-10-01
    相关资源
    最近更新 更多