web-dev-qa-db-ja.com

接続が失われた/壊れた場合、Postgresの長時間実行クエリは中止されますか?

Postgresへの接続を開いて実行時間の長いクエリを発行し、その後接続を切断した場合(たとえば、接続を開いたクライアントプロセスを強制終了する)、実行時間の長いクエリは引き続き実行されますか、それとも自動的に中止されますか?これは構成可能ですか?

(私はPostgresql 9.2.9を使用しています)

22
Rob Bednark

"場合によります"。

ネットワーク接続が失われたためにクライアントが消失した場合、クエリは通常、ネットワーク送信バッファーを満たすのに十分な行を取得するまで実行され、停止して、TCP接続がドロップするまで停止します)。 「中止します。beforeが完了すると、TCP送信バッファがいっぱいになり、正常に完了します。クエリを自動コミットするとコミットされます。

クライアントのオペレーティングシステムがTCP RST(クライアントのsegfault/crash、SIGTERM、SIGKILLなど)を介して)を介してサーバーに報告できる方法でクライアントが強制終了された場合、PostgreSQLサーバーは割り込みフラグを設定します。次にクエリが実行時に割り込みをチェックするときに、フラグが表示されて中止されます。クエリは、割り込みをチェックしないコード内でCPUに負荷のかかる処理を実行している場合があります-一部の拡張機能といくつかの場所PostgreSQLコア内-この場合、割り込みに長い間気づかずに実行を続ける可能性がありますが、自動コミットの場合は、ほとんどの場合、割り込みを確認し、完了してコミットする前に中止します。

クライアントが突然のOSの再起動などによって強制終了され、クライアントHostが突然TCP =接続がまだネットワーク上で応答できる場合、クライアントのホストがTCP RSTに応答して送信するため、Jeffが言ったように、クエリが最初に行を書き込もうとしたときにおそらく中止されます再起動後にサーバーによって送信された最初のパケットにPostgreSQLは、送信する各行で割り込みをチェックします。

この動作は構成可能ではありません。 PostgreSQLに関する限り、クライアントが立ち去った場合、その仕事はクライアントが実行していたクエリを終了することです。これを変更するには、クエリの開始時に取得できるクエリ完了トークンの種類が必要です。その後、を使用して、後で別の接続を介してクエリをサーバーに問い合わせます。基本的に、非同期/バックグラウンドクエリを実装する必要があります。おそらく素晴らしい機能ですが、現在サポートされていません。

クエリが自動コミットである場合、またはクエリがCOMMITであり、クライアントを強制終了したとき、または接続を失ったときに処理中だった場合、トランザクションがクライアントで不確定な状態になる可能性があります。コミットしたかどうかはわかりません。トランザクションのデータへの影響を調べる以外に、実際に調べる方法はありません。

それが受け入れられない場合は、 2フェーズコミット とクライアント側のトランザクションマネージャーを使用できます。

34
Craig Ringer

接続に行を戻そうと試み、破損を検出するまで、実行を続けます。したがって、行を返す前にすべての処理を実行するクエリの場合、クエリは基本的に完全に実行されます。

2
jjanes