我通过phpPgAdmin接口在大型PostgreSQL表上运行了更新语句。当它运行时间太长时,这会超时。如何释放可能的Postgres行锁?
我现在可以从该表中更新一些行,但不是全部。试图更新一些行将挂起。
行被锁定?我怎样才能让这些行更新?
我通过phpPgAdmin接口在大型PostgreSQL表上运行了更新语句。当它运行时间太长时,这会超时。如何释放可能的Postgres行锁?
我现在可以从该表中更新一些行,但不是全部。试图更新一些行将挂起。
行被锁定?我怎样才能让这些行更新?
你运行的是哪个版本的PostgreSQL?以下假设8.1.8或更高版本(它也可能适用于早期版本,我不知道)。
我认为你的意思是phpPgAdmin超时 - 只要完成查询/更新,PostgreSQL后端就会花费时间。在这种情况下,原始会话可能仍然存在,并且UPDATE查询仍在运行。我建议运行下面的查询托管的PostgreSQL服务器进程的机器上(从chapter 24 of the PostgreSQL docs采取的),看看会话是否还活着:
ps auxwww|grep ^postgres
几个行应显示:1为postmaster
主进程,并“作家”,“统计缓冲区”和“统计收集器”进程各1个。任何剩余的行都用于处理数据库连接的进程。这些行将包含用户名和数据库名称。
希望从中可以看出您执行原始UPDATE的会话是否仍然处于闲置状态。尽管从理论上讲,您可以从系统视图pg_stat_activity
中找到更详细的信息,但默认情况下,PostgreSQL未设置为填充最有用的字段(如current_query
和query_start
)。有关如何在将来启用此功能,请参阅第24章。
如果您看到会话仍在,请将其取消。您将需要以运行该进程的用户(通常为postgres
)或root身份登录 - 如果您没有自己运行服务器,请让您的DBA为您执行此操作。
还有一件事:为了更新表中的行,PostgreSQL避免使用锁。相反,它允许每个写入事务创建一个DB的新“版本”,当事务提交时它将成为“当前版本”,前提是它不会与其他事务同时发生的更新冲突。所以我怀疑你看到的“悬挂”是由其他东西引起的 - 尽管如此,我不确定。 (你是否检查过显而易见的东西,比如包含数据库的磁盘分区是否已满?)
我从来没有使用PostreSQL,但如果它与其他人类似,我会说你必须杀死连接/结束持有锁的事务。
可以看到锁。
这里是让比直接使用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%');
非常好,这工作,谢谢。请注意,当我杀死导致问题的进程时,允许一些其他正在等待锁释放的进程运行。这导致了一些更多的问题。在杀死第一个问题进程之前,我运行ps auxwww | grep^postgres时应该杀死标记为“WAITING”的进程。 – Liam 2009-06-30 11:57:20
很高兴能帮到你:) – 2009-06-30 12:01:31