0

I try to use this command to DROP the NOT NULL from "name" column, but it's get stunned and not return anything.

ALTER TABLE "school_students" ALTER COLUMN "name" DROP NOT NULL;

Here's my "school_students" table structure: enter image description here

UPDATE 1:

After running query select now() - query_start, pid, query from pg_stat_activity where state != 'idle' order by 1 desc; to check if uncommitted transaction exist, here's the result:

enter image description here

Please help, thanks.

11
  • does your statement run without errors? Commented Jan 19, 2022 at 9:10
  • 4
    Does an uncommitted transaction exist? ALTER TABLE needs a ACCESS EXCLUSIVE lock on the given table. Commented Jan 19, 2022 at 9:10
  • @TheFool yes, it just stunned. Commented Jan 19, 2022 at 9:21
  • 1
    To see current queries select now() - query_start, pid, query from pg_stat_activity where state != 'idle' order by 1 desc; Commented Jan 19, 2022 at 9:33
  • 1
    after you get the pid of the stucked query, you can end it SELECT pg_cancel_backend(pid); Commented Jan 19, 2022 at 9:48

1 Answer 1

2

The only thing that can block a short operation like this is a conflicting lock.

An ALTER TABLE statement like the one you are running requires a (short) ACCESS EXCLUSIVE lock on the table – you cannot change the table definition while it is in use. Now any concurrent transaction that has ever used the table holds at least an ACCESS SHARE lock on the table until the transaction ends, and that will block your ALTER TABLE.

To find out which session blocks you, do this:

  • Before you run ALTER TABLE, execute

    SELECT pg_backend_pid();
    

    to find out your session process number.

  • Run the ALTER TABLE that hangs.

  • Start another database session and run

    SELECT pg_blocking_pids(12345);
    

    where 12345 is the result from the query above. Now you know which sessions are blocking you.

  • Close the blocking transactions and try again. To forcibly end a hanging transaction, you can use

    SELECT pg_cancel_backend(23456);
    

    where 23456 is a process number found in the previous statement.

You should fix all bugs in the application that keep transactions open. This is always a bug. If you have no better way, set the database parameter idle_in_transaction_session_timeout so that transactions that stay open too long get closed by the server.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, it's worked. SELECT pg_backend_pid(); to select blocked command and SELECT pg_cancel_backend(23456); to remove blocked command resolved my issue.

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.