I want to perform a simple DROP VIEW ...
but it hangs.
I have run this query SELECT * FROM pg_locks WHERE NOT granted
taken from this page on Lock Monitoring.
However the following query they suggest returns no results:
SELECT bl.pid AS blocked_pid,
a.usename AS blocked_user,
kl.pid AS blocking_pid,
ka.usename AS blocking_user,
a.query AS blocked_statement
FROM pg_catalog.pg_locks bl
JOIN pg_catalog.pg_stat_activity a ON a.pid = bl.pid
JOIN pg_catalog.pg_locks kl ON kl.transactionid = bl.transactionid AND kl.pid != bl.pid
JOIN pg_catalog.pg_stat_activity ka ON ka.pid = kl.pid
WHERE NOT bl.granted;
Where should I look now ?
The syntax for the DROP VIEW statement in PostgreSQL is: DROP VIEW [IF EXISTS] view_name; view_name. The name of the view that you wish to drop.
You can remove table(s) from the database in PostgreSQL by using the statement DROP TABLE. It destroys the table with the indexes, rules, triggers, and constraints related to that table. The syntax is as follow: DROP TABLE [IF EXISTS] table_name [CASCADE | RESTRICT];
Use IF EXISTS in the statement to ensure that you aren't trying to drop a view that isn't in the database.
The CASCADE option allows you to remove the table and its dependent objects. The RESTRICT option rejects the removal if there is any object depends on the table. The RESTRICT option is the default if you don't explicitly specify it in the DROP TABLE statement.
Identify all pid from the rows in the above step and plug them into SELECT 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.
After that, you can likely DROP that table. If even that won't work, then restart postgresql, but most likely it will. Thanks for contributing an answer to Database Administrators Stack Exchange!
If you don’t use the IF EXISTS option and drop a view that does not exist, PostgreSQL will issue an error. However, if you use the IF EXISTS option, PostgreSQL issues a notice instead. Third, use the RESTRICT option to reject the removal of the view if there are any objects depending on it.
Here are the steps to find the root cause: 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. 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.
Finally I figure out what was wrong. Here are the steps to find the root cause:
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.
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.
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
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).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With