15

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

何が間違っている可能性がありますか?

4

2 に答える 2

23

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)kill -INT 1234シェルアクセスでは、同等のコマンドはとですkill 1234。(覚えておいてkill -9 1234ください、本当に悪い考えです)。

pg_locksいくつかの洞察を与えるかもしれない見解もありますが、そこから有用な情報を引き出すのはおそらくそれほど簡単ではないかもしれません。trueの場合granted、ロックは保持されgrantedます。falseの場合、クエリがロックを待機していることを意味します。pg_locksから有用な情報を抽出する方法に関するヒントを次に示します。http ://wiki.postgresql.org/wiki/Lock_Monitoring

他のすべてが失敗した場合は、おそらく簡単な解決策に取り掛かり、そのデータベースサーバーを再起動します。

于 2012-07-03T08:03:25.377 に答える
6

これはこのスレッドで説明されています。http://www.postgresql.org/message-id/75218696-61be-4730-89f6-dd6058fa9eda@a28g2000prb.googlegroups.com

トム・レーンによれば、

この作成操作は auth_user テーブルを参照し、PostgreSQL は両方のテーブルにトリガーを追加する必要があります。そのため、auth_user で AccessShare ロックを保持している長時間 (おそらくアイドル状態の) 開いているトランザクションがある場合、Postgres はブロックされ、その xact が終了してそのロックを解放するのを待ちます。他のすべては Create の後ろに並んでいます。

その PostgreSQL Mail スレッドはよく読んでいます。

于 2014-03-05T14:27:50.340 に答える