我想执行一个简单的 DROP VIEW ...
但它挂起了。
我运行了这个查询 SELECT * FROM pg_locks WHERE NOT granted
取自 Lock Monitoring 上的这个页面.
但是,他们建议的以下查询不会返回任何结果:
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;
我现在应该看哪里?
最佳答案
我终于知道哪里出了问题。以下是查找根本原因的步骤:
解决方案
第 1 步:列出未授予的请求锁
select * from pg_locks where not granted;
在我的例子中,尝试使用 AccessExclusiveLock
模式锁定我想要删除的 View 未获准。这就是我的 DROP VIEW...
挂起的原因。
第 2 步:查找其他哪些进程持有冲突锁
select * from pg_locks where relation = <oid_of_view>
我在这里列出了所有锁定或试图锁定我的 View 的进程。我发现了两个进程,一个想要删除 View 和...另一个。
第 3 步:找出其他进程正在/正在做什么
select xact_start,query_start,backend_start,state_change,state from pg_stat_activity where pid in (<list_of_other_process(es)_pid>);
我的案例中只有一个进程持有锁。令人惊讶的是,它的状态是:idle in transaction
我无法删除 View ,因为另一个进程在事务中空闲。我只是杀了它来解决我的问题。例如,如果 procpid
是 8484,假设我的 postgresql 服务器在 Linux 机器上运行,那么在 shell 中,我执行以下命令:
$ kill -9 8484
讨论
如果您遇到类似问题,您可以通过重现步骤 1、2、3 快速找出发生了什么。您可能需要自定义第 2 步,以便找到其他冲突进程。
引用资料
关于Postgresql - 为什么 DROP VIEW 命令挂起?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20373557/