我有一个"父表"并且按年分列表格,现在我需要将列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百万行,但没关系。
答案 0 :(得分:3)
支持且安全的变体是使用varchar
。这将不重写表,因为text
和ACCESS EXCLUSIVE
具有相同的磁盘表示,因此ALTER TABLE
会在一瞬间完成获得了表锁。
如果您的交易很短,您只会在UPDATE pg_attribute
SET atttypmod = -1,
atttypid = 25
WHERE attrelid = 'my_schema.my_table'::regclass
AND attname = 'column_need_change';
等待所有先前交易完成时遇到短暂停顿。
弄乱系统目录是危险的,你自己承担风险。
你可能会逃脱
{{1}}
但如果它打破了某些东西,你就可以保留它们......