「トランザクションIDの折り返し」について


10

今、私は「トランザクションIDの折り返し」についてのドキュメントを読みましたが、本当に理解できないことがあり、ドキュメントは次のURLです http://www.postgresql.org/docs/9.0/static/routine-vacuuming .html#VACUUM-FOR-WRAPAROUND

23.1.4。トランザクションIDの折り返しエラーの防止

PostgreSQLのMVCCトランザクションセマンティクスは、トランザクションID(XID)番号を比較できるかどうかに依存します。現在のトランザクションのXIDより大きい挿入XIDを持つ行バージョンは「将来」であり、現在のトランザクションからは見えません。ただし、トランザクションIDのサイズは制限されている(32ビット)ため、長時間実行されるクラスター(40億を超えるトランザクション)はトランザクションIDのラップアラウンドに悩まされます。XIDカウンターがゼロに戻り、すべての突然のトランザクションが過去は未来にあるように見えます—つまり、彼らの出力は見えなくなります。つまり、壊滅的なデータ損失です。(実際にはデータはまだ残っていますが、それが得られない場合は非常に快適です。)これを回避するには、20億トランザクションごとに少なくとも1回、すべてのデータベースのすべてのテーブルをバキュームする必要があります。

「トランザクションIDのラップアラウンドが発生します。XIDカウンターがゼロに折り返され、過去にあった突然のトランザクションはすべて未来にあるように見えます。つまり、出力が見えなくなります」というステートメントを理解できません。

誰かがこれを説明できますか?データベースでトランザクションIDのラップアラウンドが発生した後、過去にあったトランザクションが未来にあるように見えるのはなぜですか?要するに、トランザクションIDがautovacuumでラップアラウンドした後に、PostgreSQLが「データ損失」の状態になるかどうかを知りたいのです。

私の個人的な見解では、出力が64ビットで循環されないtxid_current()関数を使用して現在のトランザクションIDを取得できます。 txid_current()関数によって。ただし、PostgreSQLサーバーのシャットダウン後にpg_resetxlogリセットリセットトランザクションIDを使用します。私は正しいですか?ありがとう


私はあなたの最新の編集はおそらく新しい質問であるべきだと思います
ジャックはtopanswers.xyzを試してみます

回答:


10

データベースでトランザクションIDのラップアラウンドが発生した後、過去にあったトランザクションが未来にあるように見えるのはなぜですか?

彼らはしません。引用されたテキストは、postgresが2 31を法とする算術を使用する必要がある理由を説明しているだけです(つまり、古いトランザクションが十分に「凍結」されている限り、トランザクションはラップアラウンドできます)。

通常のXIDは、modulo-2 ^ 31演算を使用して比較されます。つまり、通常のXIDごとに、20億の「古い」XIDと20億の「新しい」XIDがあります。

具体的に:

古い行バージョンは、20億トランザクションの古いマークに達する前に、XID FrozenXIDを再割り当てする必要があります

XIDをラップすると、問題が発生します。これを防ぐために、postgresは警告を発し始め、最終的にシャットダウンし、必要に応じて新しいトランザクションの開始を拒否します。

何らかの理由でautovacuumがテーブルから古いXIDをクリアできない場合、データベースの最も古いXIDがラップアラウンドポイントから1000万トランザクションに達すると、システムは次のような警告メッセージを出力し始めます。

WARNING:  database "mydb" must be vacuumed within 177009986 transactions 
HINT:  To avoid a database shutdown, execute a database-wide VACUUM in "mydb". 

(ヒントに示されているように、手動のVACUUMで問題を解決できます。ただし、VACUUMはスーパーユーザーが実行する必要があることに注意してください。そうしないと、システムカタログの処理に失敗し、データベースのdatfrozenxidを進めることができません。)これらの警告無視されると、システムはシャットダウンし、ラップアラウンドまでに残っているトランザクションが100万未満になると、新しいトランザクションの開始を拒否します。

言い換えれば、「過去にあったトランザクションは未来にあるように見える」と「データ損失」は完全に理論上のものであり、実際にはトランザクションIDの折り返しによって引き起こされることはありません。



5

貼り付けたブロックが質問に答えているようです。それはすべて、「将来の」トランザクションを隠すために使用されるロジックに依存します。

トランザクションID(XID)カウンターは32ビットに制限されており、次の数値に達すると、古い最大トランザクションを置き換える代わりに、ゼロから新たに開始します。

さて、今はゼロなので、PostgreSQLは0より大きいトランザクションをすべて非表示にしています。そのため、トランザクション#2,147,483,633が20秒前に発生したとしても、PostgreSQLは別の2,147,483,633トランザクションでは発生しないと考えています。


1
ドキュメントは2013年12月に修正されました。XIDはmodulo-2 ^ 31を使用して計算されます。
eradman、2015
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.