Linux,php4.4,PostgreSQL 8.3&apache2でWEBページを作成しています。

フレームワークとかはつかっておりません。
DBへのConnectionPoolなども行っておりません。

大量データのSQL(SELECT)を実行したときに、待ちきれないのでページを閉じると
そのままPostgreSQLへのセッションがKillするまで永久に残ってしまいます。

これをなんとか手動でkillしないでも消す方法はないものでしょうか。
たとえば、同じページが開かれたときにとある関数を実行すると消えるとか、
cronで監視して一定時間以上起動しっぱなしのpostgresのプロセスを消す方法とか。
Postgres.confをいじればいいよ。とか。

そのような対応策があったら教えてください。

回答の条件
  • URL必須
  • 1人5回まで
  • 登録:
  • 終了:2010/02/03 14:56:09
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

ベストアンサー

id:kn1967 No.2

回答回数2915ベストアンサー獲得回数301

ポイント32pt

SELECT pg_cancel_backend(pid); でキル!

http://www.postgresql.jp/document/pg830doc/html/functions-admin....


あとは、どのようにして状態を得るか、また、どうのような状態なら、

消してしまうかという点ですが、参照系のシステムであるならば、

単純に pg_locksテーブル を見てpidを取得し、キルという流れで良いかもしれません。

このあたりの対応はシステムによりますので、ケースバイケースとしか言えませんね。


以下、余談

(余談1)

ご質問文だけで、ほぼ十分な情報となっています。不足があるとすれば、

サービスの規模や、実際の利用状況、そして実際に発行しているSQLなど、

あまりにも詳細な情報が必要になってきますので、

そこまでは公の場でのやりとりでは、あまり行わないですね。


(余談2)

公開サーバだと、セキュリティレベルの関係で、使えない手になりますが、

Webサービスが公に公開されているものではなく、社内用Webなどであれば、

echo shell_exec('ps v w -u postgres');

といった具合で長時間動き続けているpidを見つけるといった方法でも、

運用状況を見ることが出来ますので、より細かな対応が可能になります。


(余談3)

私のところは php5.3.1 PostgreSQL8.4.1 ですが

5でしか使えない pg_ 関数もあり、使い出すと結構便利だったりします。

8.4 だと高速で、見た目も判り易いSQLが書けます。

ただ、php5にアップすると余計なワーニングが出まくりとかで、

システム全体的に見直しが必要になってしまいますけど、

バージョンアップは勧めたいですね。

(当方では分析用に長いSQLを頻繁に書くのですが最高、半分の長さになり、

処理時間12倍速というトンでもないものまで出ました。

元のSQLが効率悪かったとも言えるけど・・・。)

id:pinkymonk

なるほど、ありがとうございます。

大変ためになります。

pg_lockって時間を持ってないのですね。

少し仕組みを検討します。

2010/02/02 14:43:21

その他の回答2件)

id:km1967 No.1

回答回数541ベストアンサー獲得回数40

ポイント24pt

まずはお願いなのですが、

どんなスクリプトを使ってPostgreSQLにアクセスしているのかなど

何も判らないと回答は難しくなりますので、必須だとご記憶ください。

ご質問の状況だけでは、PHPスクリプトを使ってPostgreSQLにアクセスしているのか、

別の方法でアクセスしているのかも分からないのです。

http://q.hatena.ne.jp/

id:pinkymonk

これは失礼いたしました。

PHPスクリプトを使ってPostgreSQLにアクセスしています。

httpd.confでは、extension=php_pgsql.soが有効になってます。

具体的な関数としてpg_connect関数を使用して同一セグメント内にいる別サーバーにインストールされたPostgreSQLにアクセスしています。

SQLの実行は、pg_exec関数を使っており、通常のSQLの動作(Select、update、insert&delete)に

ついてはこれまで5年間問題なく動作しています。

(途中postgreSQLやphpのバージョンアップはしました。)

SQL呼び出し後は、pg_close関数で接続を閉じるようにしています。

恐縮ですが、他に必要な情報がありましたら教えて頂ければ追記します。

2010/02/01 20:11:28
id:kn1967 No.2

回答回数2915ベストアンサー獲得回数301ここでベストアンサー

ポイント32pt

SELECT pg_cancel_backend(pid); でキル!

http://www.postgresql.jp/document/pg830doc/html/functions-admin....


あとは、どのようにして状態を得るか、また、どうのような状態なら、

消してしまうかという点ですが、参照系のシステムであるならば、

単純に pg_locksテーブル を見てpidを取得し、キルという流れで良いかもしれません。

このあたりの対応はシステムによりますので、ケースバイケースとしか言えませんね。


以下、余談

(余談1)

ご質問文だけで、ほぼ十分な情報となっています。不足があるとすれば、

サービスの規模や、実際の利用状況、そして実際に発行しているSQLなど、

あまりにも詳細な情報が必要になってきますので、

そこまでは公の場でのやりとりでは、あまり行わないですね。


(余談2)

公開サーバだと、セキュリティレベルの関係で、使えない手になりますが、

Webサービスが公に公開されているものではなく、社内用Webなどであれば、

echo shell_exec('ps v w -u postgres');

といった具合で長時間動き続けているpidを見つけるといった方法でも、

運用状況を見ることが出来ますので、より細かな対応が可能になります。


(余談3)

私のところは php5.3.1 PostgreSQL8.4.1 ですが

5でしか使えない pg_ 関数もあり、使い出すと結構便利だったりします。

8.4 だと高速で、見た目も判り易いSQLが書けます。

ただ、php5にアップすると余計なワーニングが出まくりとかで、

システム全体的に見直しが必要になってしまいますけど、

バージョンアップは勧めたいですね。

(当方では分析用に長いSQLを頻繁に書くのですが最高、半分の長さになり、

処理時間12倍速というトンでもないものまで出ました。

元のSQLが効率悪かったとも言えるけど・・・。)

id:pinkymonk

なるほど、ありがとうございます。

大変ためになります。

pg_lockって時間を持ってないのですね。

少し仕組みを検討します。

2010/02/02 14:43:21
id:e55ind No.3

回答回数162ベストアンサー獲得回数4

ポイント24pt

>大量データのSQL(SELECT)を実行したときに、待ちきれないのでページを閉じると

>そのままPostgreSQLへのセッションがKillするまで永久に残ってしまいます。

残るのは通常動作です。

SQLの見直しか、DBの最適化をするか、仕様を見直すことをお勧めします。

トリッキーな方法を使うと必ず痛い目にあいますよ。

http://q.hatena.ne.jp/answer

id:pinkymonk

おっしゃる通りですね。

SQL見直しやDB最適化や仕様変更などができてりゃ

そもそもこんな質問しないかも。

って感じです。

トリッキーでダメだったら、今までどおりときどきサーバー見て

ゾンビプロセスをkill生活をします。

2010/02/02 14:48:49
  • id:goobee
    詳しくないので、こちらに書きますね。

    ここに出ている内容は参考になりませんか?
    http://questionbox.jp.msn.com/qa306709.html
  • id:pinkymonk
    goobee様
    ありがとうございます。
    コネクションプーリングをすると本体のソースに大きく手を入れなくてはいけなくなるため
    出来れば選択したくないと考えています。
  • id:pinkymonk
    いまコメントアウトされているのですが
    deadlock_timeoutというpostgres.confの値を有効にしたらいいとかって
    話しは間違いですよね。

    この場合は、deadlockではないですよね。
  • id:kn1967
    >同じページが開かれたときにとある関数を実行すると消えるとか、

    この場合に使う手段が回答2の先頭に書いた方法。

    >cronで監視して一定時間以上起動しっぱなしのpostgresのプロセスを消す方法とか。
    >時間を持ってない

    この場合の対処例が(余談2)の psコマンド による時間監視。

    >Postgres.confをいじればいいよ

    長時間動いているプロセスの発見方法としてログ出力させるという手もあります。
    時間設定は log_min_duration_statement です。もちろん、ログ出力するように、
    設定されていなければいけませんし、ログ出力よって発生するサーバー負荷も、
    考慮しなければなりませんので、これまたケースバイケースです。

    以上はあくまでも一例です(私の知らない方法がまだまだあるはずです)が、
    PostgreSQLが標準機能として備えている(Killは比較的最近追加されました。)
    という点からも、PostgreSQL使いとしてはトリッキーなものではなく、
    多くの人が同じような悩みを、持っているという事でしょう。
    ただ、
    そちらのシステムにどれがシックリ行くのか判断つかず、列挙だけしかできませんが・・・。

この質問への反応(ブックマークコメント)

トラックバック

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません