我想执行一个简单的DROP VIEW ...
,但它会挂起。
我已在Lock Monitoring上的此页面中运行此查询SELECT * FROM pg_locks WHERE NOT granted
。
但是,他们建议的以下查询不会返回结果:
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;
我现在应该在哪里看看?
答案 0 :(得分:21)
最后我弄清楚出了什么问题。以下是找到根本原因的步骤:
select * from pg_locks where not granted;
在我的情况下,尝试使用模式AccessExclusiveLock
锁定我想要删除的视图。这就是我DROP VIEW...
挂起的原因。
select * from pg_locks where relation = <oid_of_view>
这里我列出了锁定或试图锁定我的视图的所有进程。我发现了两个进程,一个想要删除视图的进程和另一个进程。
select xact_start,query_start,backend_start,state_change,state from pg_stat_activity where pid in (<list_of_other_process(es)_pid>);
我只有一个进程在我的情况下持有锁。令人惊讶的是,它的状态是:在交易中空闲
我无法删除该视图,因为另一个进程在事务中空闲。我只是杀了它来解决我的问题。例如,如果procpid
是8484并假设我的postgresql服务器在Linux机器上运行,那么在shell中,我执行以下命令:
$ kill -9 8484
如果您遇到类似问题,可以通过复制步骤1,2,3快速了解发生了什么。您可能需要自定义第2步才能找到其他冲突的进程。
答案 1 :(得分:1)
我遇到了类似的问题,但是我没有管理员权限来杀死任何进程,因此可接受的答案对我不起作用。相反,这是我设法解决问题的方法:
SELECT * FROM pg_stat_activity;
发送到有关PostgreSQL活动的统计信息。query
列中,查找从该视图读取的查询。您可以选择只查看与用户名相关的行(username
列)或query_start
(如果知道问题何时出现)来缩小搜索范围。与您不想要的视图相关联的行可能不止一个。pid
,然后将它们逐个插入SELECT pg_terminate_backend(<pid>);
(而不是<pid>
)中并发出。现在您应该可以放弃视图了。
请注意,当您使用pg_terminate_backend()
终止后端进程时,可能会遇到一些错误。原因是终止某些进程可能会自动终止其他进程。因此,某些已识别的PID可能到时候是无效的。