Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Change column type VARCHAR to TEXT in PostgreSQL without lock table

I have a "Parent Table" and partition table by year with a lot column and now I need change a column VARCHAR(32) to TEXT because we need more length flexibility.

So I will alter the parent them will also change all partition.

But the table have 2 unique index with this column and also 1 index.

This query lock the table:

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

Also this one :

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

I see this solution :

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

But I dislike this solution.

How can change VARCHAR(32) type to TEXT without lock table, I need continue to push some data in table between the update.

My Postgresql version : 9.6

EDIT :

This is the solution I ended up taking:

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

The query lock my table between : 1m 52s 548ms for 2.6 millions rows but it's fine.

like image 512
MaximeF Avatar asked May 23 '17 18:05

MaximeF


People also ask

How do I change the datatype of a column in PostgreSQL?

First, specify the name of the table to which the column you want to change belongs in the ALTER TABLE clause. Second, give the name of column whose data type will be changed in the ALTER COLUMN clause. Third, provide the new data type for the column after the TYPE keyword.

Does Alter column lock table Postgres?

When you run an alter table statement, PostgreSQL will update the table structure and there is no locking unless you do something that needs to alter existing rows.

How do I change the constraint of a column in PostgreSQL?

For modifying the column's default value, we can use the ALTER TABLE ALTER COLUMN SET DEFAULT or DROP DEFAULT command. ALTER TABLE table_name ALTER COLUMN column_name [SET DEFAULT value | DROP DEFAULT]; We will use ALTER TABLE ADD CONSTRAINT command for adding a constraint.

Can I change varchar to text mysql?

There is no a big problem to change varchar to text because text supports more data length than varchar , but if the field has a index it must be drop and create new index with prefix col_name(length) (see CREATE INDEX syntax).


1 Answers

The supported and safe variant is to use ALTER TABLE. This will not rewrite the table, since varchar and text have the same on-disk representation, so it will be done in a split second once the ACCESS EXCLUSIVE table lock is obtained.

Provided that your transactions are short, you will only experience a short stall while ALTER TABLE waits for all prior transactions to finish.

Messing with the system catalogs is dangerous, and you do so on your own risk.

You might get away with

UPDATE pg_attribute
SET atttypmod = -1,
    atttypid  = 25
WHERE attrelid = 'my_schema.my_table'::regclass
  AND attname = 'column_need_change';

But if it breaks something, you get to keep the pieces…

like image 130
Laurenz Albe Avatar answered Sep 21 '22 03:09

Laurenz Albe