一尘不染

如何释放可能的Postgres行锁?

sql

我通过phpPgAdmin接口在大型PostgreSQL表上运行了一条更新语句。由于运行时间太长,因此超时。

我现在可以更新该表中的某些行,但不能全部更新。尝试更新某些行将挂起。

行是否被锁定?如何允许更新这些行?


阅读 199

收藏
2021-03-17

共1个答案

一尘不染

您正在运行什么版本的PostgreSQL?以下内容假设使用8.1.8或更高版本(它也可能适用于早期版本,我不知道)。

我认为您的意思是phpPgAdmin超时-
PostgreSQL后端将花费完成查询/更新的时间。在这种情况下,原始会话可能仍处于活动状态,而UPDATE查询仍在运行。我建议在托管PostgreSQL服务器进程的计算机上运行以下查询(取自PostgreSQL文档的第24章),以查看会话是否仍然存在:

ps auxwww|grep ^postgres

应该出现几行:1代表postmaster主进程,1代表“ writer”,“ stats buffer”和“ stats
collector”进程。其余所有行均用于为数据库连接提供服务的进程。这些行将包含用户名和数据库名称。

希望您可以从中看到执行原始UPDATE的会话是否仍然存在。尽管从理论上讲,您可以SELECT从系统视图中找到更多详细信息pg_stat_activity,但默认情况下,PostgreSQL并未设置为填充最有用的字段(例如current_queryquery_start)。有关将来如何启用此功能的信息,请参见第24章。

如果您看到该会话仍然存在,请杀死它。您将需要以运行进程的用户身份登录(通常是postgres)或以root用户身份登录-
如果您自己没有运行服务器,请让您的DBA替您运行。

还有一件事:为了更新表中的行,PostgreSQL避免使用锁。取而代之的是,它允许每个写入事务创建数据库的新“版本”,只要提交该事务与其他事务同时进行的更新不冲突,则该新版本将在提交事务时成为“当前版本”。因此,我怀疑您看到的“挂起”是由其他原因引起的,尽管不确定,但我不确定。(您是否检查过明显的事情,例如包含数据库的磁盘分区是否已满?)

2021-03-17