0

私は最近、ここでは繰り返さないpostgres並行性のバグに遭遇しました。元の投稿はthis linkにあります。postgres 9.5行レベルで同時実行例外がロックされる

postgresがシリアル化可能な並行処理をどのように処理するかをさらに理解しようとしています。私の状況はこれです。テーブルを読み込んだ後、読み込みの出力に基づいて挿入するストアドプロシージャが1つあります。このストアドプロシージャは、複数のクライアントによって呼び出された場合、40001の読み取り/書き込み依存関係の例外になります。

質問はこちらです。テーブルを読み込み、読み込みに基づいてテーブルに挿入するストアドプロシージャでは、一部の行のみが読み込まれると仮定します。 reads-insertのストアード・プロシージャーへの呼び出しがの異なる行に接触することが保証されている場合、並行性の例外はなくなりますか? Postgresはトランザクション中にどの行が読み取られたかを把握するのに十分なほどスマートなので、例外が発生した別のトランザクションによって特定の行の変更を正確に検出できるか?そして、もしそうなら、このメカニズムはどれくらい信頼できますか?いくつかのケースとポストグルで最適化することはできますか?ただ、安全なスローには、読み込みテーブルの変更に関する例外がありますか?

+1

なぜ結果をpostgresメーリングリストに送信しないのですか?実際の専門家と、最初にコードを書いた人を見つけることができます。 https://www.postgresql.org/list/ –

+0

* "テーブルを読み込んだ後、読み込みの出力に基づいて挿入するストアドプロシージャが1つあります。" *テーブルを読み込んで行または行は存在しますか?どのくらいのテーブルを読みますか? –

+0

いいえ、実際には3つのテーブルにわたる読み取りスパンに中間のジョイント/カウントが必要です。これは、行が存在するかどうかをチェックし、行が存在しない場合は挿入する単純なケースではありません。これは 'on'の 'on conflict'節で扱うことができます。 読み取り自体には、自動的に読み取る行の数を制限する関連する 'WHERE'節があります。 – cplusplusrat

答えて

0

最初に、あなたが与えたリンクで遭遇したのはではなく、のバグですが、意図され、文書化された動作です。

トランザクション分離レベルSERIALIZABLEを使用しています。

このモードでは、読み取られるすべての行が何もブロックされない特別なSIReadLockでロックされますが、シリアル化異常が発生した可能性があるかどうかを判断するために使用されます。

返される行は、この方法でロックされるだけでなく、クエリの実行中にアクセスされるすべてのテーブルのすべての行に留意し​​てください。したがって、実行計画にシーケンシャルスキャンがある場合、テーブルのすべて行にはSIReadLockがあります。さらに、表にこれらのロックが多すぎると、ページまたは表レベルのロックにエスカレートします。

したがって、行が不必要にロックされている可能性があります。それに加えて、矛盾を検出するために使用されるアルゴリズムは、偽陽性を報告する可能性があります(正確に計算するには高価すぎます)。

あなたが記述した場合、シリアル化エラーが発生することがありますが、すべてがシンプルに保たれ、逐次スキャンはないとは思いません。

シリアライゼーションのエラーは正常であり、SERIALIZABLEの分離レベルでは予期されるとおりです。アプリケーションは、トランザクションを再試行することにより、アプリケーションを処理する準備ができている必要があります。データの一貫性を心配する必要がないために支払う必要のある価格です。

関連する問題