【问题标题】:Postgres alter field type from float4 to float8 on huge tablePostgres 在大表上将字段类型从 float4 更改为 float8
【发布时间】:2014-05-14 11:09:24
【问题描述】:

我想在具有大量行数的表上将列数据类型从 float4 更改为 float8。如果我以通常的方式进行操作,则需要花费很多时间,并且这次我的桌子被挡住了。 是否有任何技巧可以在不重写表格内容的情况下做到这一点?

【问题讨论】:

  • 描述常用路径
  • ALTER TABLE ALTER COLUMN ...

标签: postgresql types alter-table


【解决方案1】:

ALTER TABLE ... ALTER COLUMN ... TYPE ... USING ...(或 ALTER TABLE ... ADD COLUMN ... DEFAULT ... NOT NULL 等相关内容)需要使用排他锁进行全表重写。

您可以通过一些努力,逐步解决这个问题:

  • ALTER TABLE thetable ADD COLUMN thecol_tmp newtype 没有NOT NULL

  • 在表上创建一个触发器,每次写入 thecol 时,也会更新 thecol_tmp,因此创建的新行和更新的行将获得 @987654327 的值@ 以及 newcol

  • 按 ID 范围分批,UPDATE thetable SET thecol_tmp = CAST(thecol AS newtype) WHERE id BETWEEN .. AND ..

  • thecol_tmpALTER TABLE thetable ALTER COLUMN thecol_tmp SET NOT NULL; 中填充所有值后。

  • 现在交换列并将触发器放在单个 tx 中:

    • BEGIN;
    • ALTER TABLE thetable DROP COLUMN thecol;
    • ALTER TABLE thetable RENAME COLUMN thecol_tmp TO thecol;
    • DROP TRIGGER whatever_trigger_name ON thetable;
    • COMMIT;

理想情况下,我们应该有一个 ALTER TABLE ... ALTER COLUMN ... CONCURRENTLY 在 PostgreSQL 中执行此操作,但没有人实现它。然而。

【讨论】:

  • 我的情况更复杂 :-( 我的表是带有分区的父表(继承表),每个月有一张表的数据。所以如果我更改父表 - 所有继承的表都必须更新和父表表此时已锁定。每个继承的表都有 10-30 Gb
  • 如果您在原始问题中提及此类重要细节会有所帮助。尽管我没有尝试过,但我没有看到对继承表使用相同方法的基本障碍。它会使添加 not null 约束的速度变慢,但否则我认为不需要长锁。
  • 好的。你的方式有帮助:-)
猜你喜欢
  • 2023-03-20
  • 2017-07-07
  • 2023-03-11
  • 2016-06-30
  • 1970-01-01
  • 1970-01-01
  • 2020-11-10
  • 2017-02-13
  • 1970-01-01
相关资源
最近更新 更多