在没有锁定表的情况下将PostgreSQL中的列类型VARCHAR更改为TEXT

时间:2017-05-23 18:57:09

标签: postgresql alter-table

我有一个"父表"并且按年分列表格,现在我需要将列VARCHAR(32)更改为TEXT,因为我们需要更长的灵活性。

所以我将更改父级,他们也将更改所有分区。

但是该表在此列中有2个唯一索引,还有1个索引。

此查询锁定表:

ALTER TABLE my_schema.my_table
ALTER COLUMN column_need_change TYPE VARCHAR(64) USING 
column_need_change :: VARCHAR(64);

还有这个:

ALTER TABLE my_schema.my_table
ALTER COLUMN column_need_change TYPE TEXT USING column_need_change :: TEXT;

我看到了这个解决方案:

UPDATE pg_attribute SET atttypmod = 64+4
WHERE attrelid = 'my_schema.my_table'::regclass
AND attname = 'column_need_change ';

但我不喜欢这个解决方案。

如果没有锁定表,如何将VARCHAR(32)类型更改为TEXT,我需要继续在更新之间推送表格中的一些数据。

我的Postgresql版本:9.6

编辑:

这是我最终采取的解决方案:

ALTER TABLE my_schema.my_table
ALTER COLUMN column_need_change TYPE TEXT USING column_need_change :: TEXT;

查询将我的表锁定在:1m 52s 548ms,行数为2.6百万行,但没关系。

1 个答案:

答案 0 :(得分:3)

支持且安全的变体是使用varchar。这将重写表,因为textACCESS EXCLUSIVE具有相同的磁盘表示,因此ALTER TABLE会在一瞬间完成获得了表锁。

如果您的交易很短,您只会在UPDATE pg_attribute SET atttypmod = -1, atttypid = 25 WHERE attrelid = 'my_schema.my_table'::regclass AND attname = 'column_need_change'; 等待所有先前交易完成时遇到短暂停顿。

弄乱系统目录是危险的,你自己承担风险。

可能会逃脱

{{1}}

但如果它打破了某些东西,你就可以保留它们......