3

I have a postgres table with millions of record in it. Now I want to add new column to that table called "time_modified" with the value in another column "last_event_time". Running a migration script is taking long time , so need a simple solution to run in production.

3
  • There is no "simple" solution. The only way is to run an update after you have added the column. Commented May 18, 2017 at 6:17
  • do you affraid block table for others process ? Commented May 18, 2017 at 6:24
  • Can not afford to lock the table for long duration as db is critical for client apps Commented May 18, 2017 at 11:06

2 Answers 2

4

Assuming that the columns are timestamps you can try:

alter table my_table add time_modified text;
alter table my_table alter time_modified type timestamp using last_event_time;
Sign up to request clarification or add additional context in comments.

5 Comments

Wouldn't an update be more efficient? The alter table uses an exclusive lock on the table while an update would at least allow selecting from it while the update is running.
It depends on server load and other clients. Once we obtain a lock the operation should be much faster than an update. I would do this on Sunday at 4 am ;)
Thanks klin .This solution better than update but only concern about locking the table. Is there any better option ?
I don't think there is a better solution. You have to choose between locking all rows for write and an exclusive lock on the table, and it depends on the current server load. I think the key is to choose the right moment.
If the server is permanently heavily loaded, you can perform updates in chunks. Of course, these partial updates have to be executed in their own transactions (not all in a single transaction).
0

I suggest use function with pg_sleep, which wait between iteriation in loop

This way don't invoke exclusive lock and others locks on your_table.

SELECT pg_sleep(seconds);

But time of execute is long

alter table my_table add time_modified timestamp;

CREATE OR REPLACE FUNCTION update_mew_column()
  RETURNS void AS
$BODY$
DECLARE
    rec record;

BEGIN
    for rec in (select id,last_event_time from your_table) loop

        update your_table set time_modified = rec.last_event_time where id = rec.id;
        PERFORM pg_sleep(0.01);

    end loop;
END;
$BODY$
  LANGUAGE plpgsql VOLATILE

and execute function:

select update_mew_column();

1 Comment

This will simply increase the time the locks are held.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.