6

トランザクションの分離レベルに関する PostgreSQL のドキュメントでは、以下を読むことができます。

マスターのシリアライズ可能トランザクション内ですべての永続的なデータベース書き込みを実行すると、すべてのスタンバイが最終的に一貫した状態に到達することが保証されますが、スタンバイで実行される反復可能読み取りトランザクションは、マスターでのシリアライズ可能トランザクションのシリアル実行と矛盾する一時的な状態を確認することがあります。主人。

上記のテキストはhttp://www.postgresql.org/docs/9.4/static/transaction-iso.htmlの下部にあります

ホット スタンバイで実行された Repeatable Read トランザクションが一貫性のない一時的な状態になる可能性があるのは、どのような状況ですか?

4

2 に答える 2

5

Geir Bostad からの回答は正しいです。多くの場合、これについて理解するのに苦労するので、例と考えられる回避策を提供するためだけに回答しています。他の回答で参照されているWikiページに加えて、バッチが閉じられていると見なされているが、バッチの最終的な詳細をまだ表示できない「預金レポート」の例を含む、例のためだけの別のWikiページがあります。

ホット スタンバイは読み取り専用であるため、一時的なシリアライゼーションの異常しか確認できません。データは、最終的に後続のトランザクションで一貫した状態に落ち着きます。これは、プライマリ サーバーの反復可能な読み取りトランザクションで発生する可能性があるものと同じであり、プライマリ サーバーのシリアル化可能なトランザクションでは発生しません。混乱を避けるために、シリアライズ可能なトランザクションはホット スタンバイでは許可されていません。これは、真にシリアライズ可能なトランザクションの動作が (まだ) 保証されていないためです。DEFERRABLEのオプションと同様に、異常が発生するリスクなしにシリアライズ可能なトランザクションを開始できるポイントを特定するために、WAL ストリームに情報を追加するという話がありましたSTART TRANSACTION。これ (またはそれに似たもの) は、将来のバージョンで追加される可能性があります。

スナップショット分離を使用する読み取り専用トランザクション (Oracle または 9.1 より前のバージョンの PostgreSQL でシリアル化可能と識別されたトランザクションを含む) の場合、最も一般的なタイプの異常は、トランザクションに対して「クローズ」と表示される SELECT リストまたはバッチの要約であると思われます。バッチに含める必要があるすべての作業を表示せずに。これを確認するには、バッチを閉じるトランザクションは、バッチの詳細を変更するいくつかのトランザクションと「重複」(同時に実行) する必要があり、バッチを閉じるトランザクションは最初にコミットする必要があり、次に (バッチを閉じるトランザクションがコミットされた後、バッチの詳細を変更するトランザクションの前に)コミット) 読み取り専用トランザクションを開始し、そのスナップショットを取得する必要があります。

これを防ぐための最も簡単な方法は、プライマリで読み取りと書き込みの依存関係から書き込みと書き込みの競合に「競合を促進」することです。たとえば、上記の「預金レポート」の例では、deposit_total 列をコントロール テーブルに追加できます。コントロール テーブルは、deposit_no がインクリメントされたときに AFTER トリガーによってゼロに設定されます。また、AFTER トリガーをレシート テーブルに追加して、各レシートの金額に基づく金額。これにより、制御レコードの書き込み競合に基づいてシリアライゼーション エラーが発生し、異常がレプリカに伝播されなくなります。

于 2015-06-22T17:41:37.317 に答える
4

これは、バッチ処理や同様のアプリケーションで発生する可能性があるようです。

SSIに関する wiki ページでこのトピックに関する情報をいくつか見つけました。また、ホット スタンバイでシリアライゼーションを処理する方法について議論している postgresql-hackers メーリング リストから背景の詳細​​をいくつか見つけました。

Kevin Grittner は彼の投稿で次のように書いています。

私の意見では、これが発生する最も一般的で憂慮すべき状況はバッチ処理です。これは金融アプリケーションでは非常に一般的であり、他の多くの場所でも見られる傾向があります。

[..]

ただし、スタンバイのクエリは、トランザクション ストリームの同じポイントでマスターで実行されるとシリアライゼーションの失敗を引き起こすクエリを実行するときに一時的な異常を確認できます。これは、2 つの同時トランザクションのうち、 書き込まれた内容を読み取ることができないために 2 番目に実行され たように見えるトランザクションが最初にコミットされた場合にのみ発生します。

[..]

SSI では、これを防ぐためにこれらのトランザクションの 1 つがキャンセルされます。私たちの実装では、バッチを閉じる更新が完了することを常に許可し、トランザクション内のアクションのタイミングに応じて、詳細の挿入または選択がシリアル化の失敗でロールバックされます。挿入が失敗した場合は、再試行でき、新しいバッチに配置されます。これにより、それを省略したバッチのリストが OK になります。バッチの詳細のリストがキャンセルされた場合、問題が認識される前に古いバッチへの挿入がコミットされたことが原因であるため、select をすぐに再試行すると完全なバッチの内容が表示されます。

ホット スタンバイは、マスターでの述語のロックとトランザクションのキャンセルに実際に参加することはできません。

于 2015-03-03T16:36:38.770 に答える