我通过phpPgAdmin接口在大型PostgreSQL表上运行了更新语句。这个时间太久了。
我现在可以更新该表中的某些行但不是全部。尝试更新某些行将会挂起。
行被锁定了吗?如何允许更新这些行?
答案 0 :(得分:74)
可以看到锁。
这是一个让它比直接使用pg_locks更容易的视图:
CREATE OR REPLACE VIEW public.active_locks AS
SELECT t.schemaname,
t.relname,
l.locktype,
l.page,
l.virtualtransaction,
l.pid,
l.mode,
l.granted
FROM pg_locks l
JOIN pg_stat_all_tables t ON l.relation = t.relid
WHERE t.schemaname <> 'pg_toast'::name AND t.schemaname <> 'pg_catalog'::name
ORDER BY t.schemaname, t.relname;
然后你只需从视图中选择:
SELECT * FROM active_locks;
用以下方法杀死它:
SELECT pg_cancel_backend('%pid%');
答案 1 :(得分:20)
你在运行什么版本的PostgreSQL?以下假定为8.1.8或更高版本(它也可能适用于早期版本,我不知道)。
我认为你的意思是phpPgAdmin超时 - PostgreSQL后端将花费很长时间来完成查询/更新。在这种情况下,原始会话可能仍然存在且UPDATE查询仍在运行。我建议在托管PostgreSQL服务器进程的机器上运行以下查询(取自chapter 24 of the PostgreSQL docs),以查看会话是否仍然存在:
ps auxwww|grep ^postgres
应该出现几行:1表示postmaster
主进程,1表示“writer”,“stats buffer”和“stats collector”进程。任何剩余行都用于为DB连接提供服务的进程。这些行将包含用户名和数据库名称。
希望您可以看到您执行原始UPDATE的会话是否仍然存在。虽然理论上你可以通过SELECT
从系统视图pg_stat_activity
找到更详细的信息,但默认情况下PostgreSQL没有设置为填充最有用的字段(例如current_query
和{{} 1}})。有关如何在将来启用此功能,请参阅第24章。
如果您看到会话仍在那里,请将其删除。您需要以运行该进程的用户(通常为query_start
)或root用户身份登录才能执行此操作 - 如果您不自行运行服务器,请让DBA为您执行此操作。
还有一件事:为了更新表中的行,PostgreSQL避免使用锁。相反,它允许每个写入事务创建数据库的新“版本”,在事务提交时成为“当前版本”,前提是它与其他事务同时进行的更新不冲突。所以我怀疑你所看到的“悬挂”是由其他东西造成的 - 尽管如此,我不确定。 (您是否已检查过明显的事情,例如包含数据库的磁盘分区是否已满?)
答案 2 :(得分:2)
这将清除所有表上的所有锁。
SELECT pg_terminate_backend(pid)
FROM pg_stat_activity
WHERE pid <> pg_backend_pid();
答案 3 :(得分:1)
要从Postgres释放可能的锁,我通常会按顺序进行操作。
通过运行以下查询在数据库中查找长期运行的查询。这将帮助您获取长时间运行的查询的PID,这会阻止您的更新。
SELECT
pid,
now() - pg_stat_activity.query_start AS duration,
query,
state
FROM pg_stat_activity
WHERE (now() - pg_stat_activity.query_start) > interval '5 minutes';
,或者是否可以通过运行此查询来找出哪些进程在特定表上持有锁
SELECT *
FROM pg_locks l
JOIN pg_class t ON l.relation = t.oid AND t.relkind = 'r'
WHERE t.relname = 'Bill';
一旦找出了“活动”的PID并阻止了更新,则可以通过运行此查询将其杀死。消灭该过程需要一些时间。
SELECT pg_cancel_backend(__pid__);
通过运行查询2检查进程是否被终止。如果它仍然处于活动状态,则通过运行此查询来终止该过程。
SELECT pg_terminate_backend(__pid__);
答案 4 :(得分:-3)
我从未使用PostgreSql,但如果它与其他人类似,我会说你必须终止连接/结束持有锁的交易。