Postgresql - Why is DROP VIEW command hanging?
I had a similar problem but the accepted answer didn't work for me as I do not have admin access to kill any process. Instead, this is how I managed to solve the problem:
- Issue
SELECT * FROM pg_stat_activity;
to get the stats about the PostgreSQL activities. - In
query
column, look for the queries that read from that view. You may choose to narrow down your search by only looking into the rows related to your username (usingusername
column) orquery_start
if you know when the issue emerged. There could be more than one row associated with your unwanted view. - Identify all
pid
from the rows in the above step and plug them intoSELECT pg_terminate_backend(<pid>);
(instead of<pid>
) one by one and run them.
Now you should be able to drop your view.
Please note that as you terminate the backend processes using pg_terminate_backend()
, you may face some errors. The reason is that terminating some process may automatically end other processes. Therefore, some of the identified PIDs might be invalid by the time.
Finally I figure out what was wrong. Here are the steps to find the root cause:
Solution
Step 1 : List requested locks not granted
select * from pg_locks where not granted;
In my case, an attempt to lock, with the mode AccessExclusiveLock
, the view I want to drop was not granted. This is why my DROP VIEW...
hangs.
Step 2 : Find which other process(es) held a conflicting lock
select * from pg_locks where relation = <oid_of_view>
Here I list all processes locking or trying to lock on my view. I found out two processes, the one that want to drop the view and... another one.
Step 3 : Find out what other process(es) is/are doing now
select xact_start,query_start,backend_start,state_change,state from pg_stat_activity where pid in (<list_of_other_process(es)_pid>);
I had only one process holding a lock in my case. Surprisingly, its state was : idle in transaction
I was not able to drop the view because another process was idle in transaction. I simply kill it to solve my issue. For example, if the procpid
was 8484 and let's suppose my postgresql server runs on a Linux box, then in the shell, I execute the following command:
$ kill -9 8484
Discussion
If you face similar issue, you can quickly find out what's going on by reproducing steps 1,2,3. You may need to customize Step 2 in order to find other conflicting process(es).
References
- Lock Monitoring
- Lock Dependency Information
- View Postgresql Locks