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


20

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

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

回答:


32

"場合によります"。

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

クライアントのオペレーティングシステムがTCP RSTを介してサーバーに報告できる方法でクライアントが強制終了された場合(クライアントsegfault / crash、SIGTERM、SIGKILLなど)、PostgreSQLサーバーは割り込みフラグを設定します。クエリの実行時に割り込みが次にチェックされると、フラグが表示され、中止されます。時々、クエリが割り込みをチェックしないコード内でCPUを大量に使用する場合があります-いくつかの拡張機能、およびPostgreSQLコア内のいくつかの場所-この場合、長時間割り込みに気付かずに実行を継続する場合があります。ただし、オートコミットの場合は、完了してコミットする前に、割り込みと中断がほとんど常に表示されます。

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

この動作は構成できません。PostgreSQLに関する限り、クライアントがなくなるかどうかは、クライアントが実行していたクエリを終了することです。これを変更するには、クエリの開始時に取得できるクエリ完了トークンを必要とし、後で別の接続を介してサーバーにクエリについて尋ねます。基本的に、非同期/バックグラウンドクエリを実装する必要があります。おそらく素晴らしい機能ですが、現在サポートされていません。

クエリが自動コミットである場合、またはクエリがCOMMITクライアントを殺した/接続を失った時点で飛行中だった場合、トランザクションが不確定な状態になる可能性があります。コミットされていません。トランザクションがデータに与える影響を探す以外に、見つける方法はありません。

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


1
うわー、ちょうど私が探していたもの、優れた詳細な答え!ありがとう@Craig_Ringer!
ロブベッドナーク14年


2

接続に行を戻そうとし、破損を検出するまで実行を続けます。そのため、行を返す前にすべての作業を行うクエリの場合、基本的に完了まで実行されます。


ありがとう@jjanes。これを示すドキュメントまたはソースコードを指摘できますか?
ロブBednark 14年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.