まず、マルチバージョン同時実行制御(MVCC)を読むことは背景として役立つと思います。 この答えの背景として。
InnoDBはMVCCを実装しています。つまり、通常のSELECT
に非ロック読み取りを使用できます。 。これには「スナップショット」を作成する必要はなく、実際、InnoDBにはオブジェクトとしてのスナップショットの実際の概念はありません。代わりに、データベース内のすべてのレコードは、それ自体のバージョン番号を追跡し、行を以前のバージョンに変更する「元にできるログ」レコード(まだ存在する場合と存在しない場合があります)への「ロールポインター」を維持します。古いバージョンのレコードが必要な場合は、現在のバージョンが読み取られ、それらのロールポインターが追跡され、十分に古いバージョンのレコードが生成されるまでレコードが適用されます。
通常、システムはこれらの取り消しログを常にクリーンアップし、それらが消費するスペースを再利用しています。
長時間実行されるトランザクションはいつでも (必ずしも単一のクエリである必要はありません)が存在する場合、そのトランザクションを満たすためにすべてのレコードの十分に古いバージョンを十分に再作成するために、UNDOログを保持する(パージしない)必要があります。非常にビジーなシステムでは、これらのUNDOログは非常に迅速に蓄積され、ギガバイトのスペースを消費する可能性があります。さらに、特定の個々のレコードが非常に頻繁に変更される場合、そのレコードをクエリを満たすのに十分な古いバージョンに戻すと、非常に多くの元にログアプリケーション(数千)が必要になる可能性があります。
それが「長時間実行クエリ」を高価にし、眉をひそめる原因です。システムテーブルスペースにUNDOログを保持するためのディスク領域の消費量が増加し、読み取り時に行バージョンを元に戻すUNDOログレコードアプリケーションが原因でパフォーマンスが低下します。
一部のデータベースは、消費できる最大量のUNDOログスペースを実装しており、その制限に達すると、古いUNDOログレコードを破棄し、実行中のトランザクションを無効にし始めます。これにより、ユーザーに「スナップショットが古すぎます」というエラーメッセージが生成されます。 InnoDBにはそのような制限はなく、無期限に蓄積できます。