【问题标题】:Postgres client locking up when creating new tablePostgres客户端在创建新表时锁定
【发布时间】:2012-07-03 15:06:21
【问题描述】:

我正在尝试在 postgres 中创建一个新表,但是当我这样做时,它只是在 CREATE TABLE 调用之后挂起。

$ sudo usermod -s /bin/bash postgres
$ sudo su - postgres
postgres@host:~$ psql ranking_analytics
psql (8.4.8)
Type "help" for help.

ranking_analytics=# BEGIN;
BEGIN
ranking_analytics=# CREATE TABLE "about_contactmessage" (
ranking_analytics(#     "id" serial NOT NULL PRIMARY KEY,
ranking_analytics(#     "user_id" integer NOT NULL REFERENCES "auth_user" ("id") DEFERRABLE INITIALLY DEFERRED,
ranking_analytics(#     "subject" text NOT NULL,
ranking_analytics(#     "message" text NOT NULL,
ranking_analytics(#     "recorded_time" timestamp with time zone NOT NULL
ranking_analytics(# )
ranking_analytics-# ;
NOTICE:  CREATE TABLE will create implicit sequence "about_contactmessage_id_seq" for serial column "about_contactmessage.id"

然后它会无限期地坐在这里直到我CTRL-C它。

数据库中还有其他表,但此表尚不存在:

ranking_analytics=# \d about_contactmessage
Did not find any relation named "about_contactmessage".

我可以毫无问题地对数据库中的其他表进行插入和删除查询:

ranking_analytics=# insert into locations_continent (continent_name) VALUES ('testing');
INSERT 0 1
ranking_analytics=# delete from locations_continent where continent_name = 'testing';
DELETE 1

机器上有足够的驱动器空间:

$ df -H
Filesystem             Size   Used  Avail Use% Mounted on
/dev/xvda               21G   2.3G    18G  12% /
devtmpfs               255M   132k   255M   1% /dev
none                   257M   476k   256M   1% /dev/shm
none                   257M    54k   257M   1% /var/run
none                   257M      0   257M   0% /var/lock

有什么想法可能是错的吗?

【问题讨论】:

  • sudo -u postgres psql 更容易,顺便说一句。

标签: postgresql


【解决方案1】:

如果重新启动 postgres 是一个选项,那么这很可能会解决问题,并且可以节省您花时间阅读此答案的其余部分 :-)

检查pg_stat_activity 视图,可能有一些其他事务阻止了架构更改。

select * from pg_stat_activity 
where 
wait_event_type is NULL and xact_start is not NULL order by xact_start;

(pg_stat_activity 在每个主要的 pg 版本中都会有所改变,对于旧版本试试这个):

select * from pg_stat_activity 
where 
not waiting and xact_start is not NULL order by xact_start;

显示的第一行可能是导致问题的行。它通常是一个“空闲事务”——这很可能会持有锁,如果它是一个旧事务,它也可能会破坏性能。可能程序员忘记确保以“提交”或“回滚”结束事务,或者可能由于网络问题某些数据库会话卡住了。

要使用 pid 1234 终止事务,请使用 select pg_cancel_backend(1234);,如果失败,请使用 select pg_terminate_backend(1234)。通过 shell 访问,等效的命令是 kill -INT 1234kill 1234。 (请记住,kill -9 1234 是一个非常糟糕的主意)。

还有一个视图pg_locks 可能会提供一些见解,尽管从中获得任何有用的信息可能并不那么容易。如果granted 为真,则持有锁,当granted 为假时,表示查询正在等待锁。这里有更多关于如何从 pg_locks 中提取有用信息的提示:http://wiki.postgresql.org/wiki/Lock_Monitoring

如果一切都失败了,那么可能是时候采用简单的解决方案了,重新启动数据库服务器。

【讨论】:

  • 我发现刚刚挂在ALTER TABLE "about_contactmessage" ADD CONSTRAINT "user_id_refs_id_2a9a546ebb1d6a8b" FOREIGN KEY ("user_id") REFERENCES "auth_user" ("id") DEFERRABLE INITIALLY DEFERRED; 上的查询,我用select pg_cancel_backend(30969); 杀死了它并再次运行了create table 命令,但它仍然挂起。 ALTER TABLE 语句是当时唯一在 DB 上运行的语句。
  • 我刚刚看了pg_locks,里面全是整数。我将重新启动 postgres 并尝试再次创建表。
  • 杀死挂起的进程,重新启动 postgres 然后再次尝试修复它的组合。非常感谢!
  • 我会在答案中添加“restart postgres”。我想过,但觉得太傻了;-)
  • “等待”列是 replaced,“wait_event_type”和“wait_event”介于 9.5 和 9.6 之间。您可以在查询中将其替换为wait_event_type IS NULL
【解决方案2】:

这在这个线程中有解释; http://www.postgresql.org/message-id/75218696-61be-4730-89f6-dd6058fa9eda@a28g2000prb.googlegroups.com

根据汤姆·莱恩的说法,

此创建操作引用 auth_user 表,并且 PostgreSQL 应该向这两个表添加触发器。因此,如果有一个长时间运行的(可能是空闲的)打开事务在 auth_user 上持有 AccessShare 锁,则 Postgres 会被阻塞,等待该 xact 完成并释放其锁。其他一切都在 Create 后面排队。

那个 PostgreSQL 邮件线程很好读。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-02-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多