tl; dr:コミット後にデータを読み取る最初のプロセスは、ヒントビットを設定します。それはページを汚し、書き込みアクティビティを作成します。他のことVACUUM
(ただし、他のコマンドではありません)は、適切な場合、ページをすべて可視としてマークします。VACUUM
タプルをフリーズするには、最終的にテーブルにヒットする必要があります。
挿入後に実行する必要がある作業は、少なくとも他の作業の意味ではVACUUM
通常、クリーンアップではありません。詳細を説明する前に、この回答は現在の(未リリースの)9.6コードに基づいていることに注意してください。
MVCCのため、Postgresがタプルをクエリに表示する必要があるかどうかを評価するたびに、タプルを作成したトランザクション(xmin非表示フィールドに記録)がコミットされたかどうか、およびその他の基準を考慮する必要があります。このチェックはコストがかかるため、現在開いているすべてのトランザクションにトランザクションが認識されるとすぐに、それを示す「ヒントビット」がタプルヘッダーに設定されます。そのビットの設定はページを汚すため、ディスクに書き込む必要があります。データを読み取る次のコマンドSELECT
が突然大量の書き込みトラフィックを作成している場合、これは非常に混乱する可能性があります。VACUUM
挿入のコミット後にa を実行すると、それが回避されます。別の重要な違いはVACUUM
(ページのクリーンアップロックを取得している限り)ページ上のタプルを常にヒントしますが、他のほとんどのコマンドは、コマンドの開始前に挿入トランザクションがコミットされた場合にのみヒントを出します。
これらのヒントビットをすべて記述することの重要な点はVACUUM
、調整できることです(デフォルトで自動バキュームは調整されます)。他のコマンドは調整されず、可能な限り迅速にダーティデータを生成します。
VACUUM
ページをすべて可視としてマークするための唯一の方法です。これは、一部の操作(特に、インデックスのみのスキャン)のパフォーマンスに関する重要な考慮事項です。大規模な挿入を行う場合、新たに挿入されたタプル以外の多くのページが存在する可能性が非常に高くなります。VACUUM
これらのページをすべて可視としてマークする可能性がありVACUUM
ますが、これは開始時に最も古い実行中のトランザクションがデータを挿入したトランザクションよりも新しい場合のみです。
MVCCの動作方法により、約20億トランザクション以上前に挿入されたタプルは、「凍結」としてマークする必要があります。デフォルトでは、autovacuumは200Mトランザクションごとにそれを実行します。一括挿入後、vacuum_freeze_min_ageを0に設定して手動バキュームを実行すると、その影響を軽減できます。より積極的に、挿入後にテーブルで実行できます。これは、次のフリーズスキャンが発生するときに「クロックをリセット」します。VACUUM FREEZE
特定の詳細を知りたい場合は、insideをHEAPTUPLE_LIVE
呼び出した後のケースを見てください。自身も参照して、と比較してください。HeapTupleSatisfiesVacuum()
lazy_scan_heap()
HeapTupleSatisfiesVacuum()
HeapTupleSatisfiesMVCC()
私の興味深いプレゼンテーションが他に2つあります。最初のビデオはhttp://www.pgcon.org/2015/schedule/events/829.en.htmlから入手できますが、2番目のビデオ(https://www.youtubeから)com / watch?v = L8nErzxPJjQ
EXPLAIN (ANALYZE, BUFFERS) outputs. But, if I understand things correctly, some of the hint bits (at least
* COMMITTED`の一部のダーティページについても説明して*INVALID
います。また、COMMIT
またはROLLBACK
で既に設定できます(できます)。