2012-04-25 10 views
15

"DROP TABLE"コマンドを使用していくつかのテーブルを削除しようとしていますが、未知の理由でプログラムが単に「座って」いて、データベース内のテーブルを削除しません。法案の製品を参照するために使用されPostgresql DROP TABLEが機能しない

製品、ビルとBill_Products:

は、私は、データベース内の3つのテーブルを持っています。

私は商品を削除/削除できましたが、請求書とBill_Productsで同じことをすることはできません。 同じ"DROP TABLE Bill CASCADE;"コマンドを発行していますが、コマンドラインだけが停止します。私はまた、CASCADEオプションのないシンプルなバージョンを使用しました。

これはなぜ起こっているのでしょうか?

更新:

私はそれが法案への製品からいくつかの参照を保持するためにデータベース用可能であり、それはビル・テーブルは削除されませんなぜ多分それはだと考えてきました。

そのため、私は単純なSELECT * from Bill_Productsを発行しました。数十秒後に(奇妙なことに、それは空のテーブルがあるような長い時間続くのが普通だと思っていないので)テーブルとその内容を印刷します。 (だから明らかに商品からビルに残っている参照はありません)。

SELECT * 
    FROM pg_locks l 
    JOIN pg_class t ON l.relation = t.oid AND t.relkind = 'r' 
WHERE t.relname = 'Bill'; 

の出力はそれが並行して、あなたのテーブルを使用して他のセッションをしているし、あなたがそれをドロップするAccess Exclusiveロックを取得することができないということかもしれないです何

+0

何CASCADEをしていない程度。おそらく制約は、現在欠けている製品を指していた可能性があります – Randy

+0

これも試してみましたが効果はありません。 –

+1

"コマンドラインだけが停止します"これはどういう意味ですか? 'psql'がクラッシュ、ハング、フリーズしますか?あなたはそれを殺さなければなりませんか? Ctrl-Cは何をするのですか?私はちょうど '屋台'を定義していると思う。またはpsqlを使用していませんか? – alan

答えて

26

+1

'psdemo => pg_locksからのSELECT * pg_class t on l.relation = t.oid AND t.relkind = 'r' WHERE t.relname =" ps_bill "; エラー:列 "ps_bill"が存在しません 行1:... ation = t.oid AND t.relkind = 'r' WHERE t.relname = "ps_bill"; ' –

+0

リテラル値の場合は、一重引用符アポストロフィ)。 PostgreSQLは、二重引用符を*識別子*をラップして扱う際のSQL標準に準拠しています。 – kgrittn

+2

ありがとうございましたが、私は簡単な再起動でそれを修正することができました。それは、愚かで分かりにくいことではなく、私がしたことですが、問題を取り巻く最短の方法でした。私はあなたの答えに投票したので、あなたの助けに感謝しています。私は実際にテーブルにロックを保持してトランザクションがあったと思う。 –

4

同じ問題がありました。

テーブルにロックがありませんでした。

リブートが助けられました。

+0

私と同じこと。再起動する必要はなく、postgresqlを再起動するだけでした。 –

+0

同じです。再起動する必要があります – anvd

5

だから私は同じ問題を解決しようとするいくつかの時間のために壁に頭を打った、そしてここで私のために働いたソリューションは、次のとおりです。

チェックPostgreSQLがコミットされていないの保留準備されたトランザクションを持っている場合か、ロールバック:

SELECT database, gid FROM pg_prepared_xacts; 

あなたが結果を得る場合は、GID各トランザクションのためにあなたが問題を有するデータベースからROLLBACK実行する必要があります。

ROLLBACK PREPARED 'the_gid'; 

詳細については、click hereを参照してください。

3

ちょうど

SELECT pid, relname 
FROM pg_locks l 
JOIN pg_class t ON l.relation = t.oid AND t.relkind = 'r' 
WHERE t.relname = 'Bill'; 

を行い、その後、

1234クエリの結果から、実際のP​​IDである
kill 1234 

により、すべてのpidを殺します。

psql -c "SELECT pid FROM pg_locks l 
    JOIN pg_class t ON l.relation = t.oid AND t.relkind = 'r' 
    WHERE t.relname = 'Bill';" | tail -n +3 | head -n -2 | xargs kill 
+0

質問を投稿してから3年以上経っても、あなたのソリューションに来てくれてありがとうと感謝します。しかし、私の質問は「relname」とは何でしょうか? –

+1

@RaduGheorghiu relnameは実際にはテーブル名です。 – chemikadze

0

古い質問をしかし、同様の問題に遭遇した:あなたはこのようにすべて一緒にパイプすることができます

(あなたは、すべて手動でPIDコピー&ペーストする必要はありません)。データベースを再起動できませんでしたので、このシーケンスが動作するまでいくつかテストしました。

  • truncate table foo;
  • 同時にインデックスを削除するfoo_something;回4-5x
  • alter table foo dropカラムwhatever_foreign_key;回3x
  • alter table foo drop column id;
  • ドロップテーブルfoo;
関連する問題