このページは機械翻訳したものです。
InnoDB
はマルチバージョンストレージエンジンです。並列実行やロールバックなどのトランザクション機能をサポートするために、変更された行の古いバージョンに関する情報が保持されます。 この情報は、テーブルスペース内にロールバックセグメントと呼ばれるデータ構造で (Oracle では類似したデータ構造のあとに) 格納されます。 InnoDB
では、トランザクションのロールバックで必要となる取り消し操作を実行するために、ロールバックセグメント内の情報が使用されます。 また、この情報は、一貫性読み取りのために行の初期バージョンを構築する際にも使用されます。
InnoDB
は内部的に、データベース内に格納された各行に 3 つのフィールドを追加します。 6 バイトの DB_TRX_ID
フィールドは、行を挿入または更新した最後のトランザクションに対して、トランザクション識別子を指示します。 また、行内の特別ビットが削除されたとマークするように設定されている場合、削除は内部的に更新として処理されます。 各行には、ロールポインタと呼ばれる 7 バイトの DB_ROLL_PTR
フィールドも含まれています。 ロールポインタは、ロールバックセグメントに書き込まれた Undo ログレコードを示しています。 行が更新された場合は、Undo ログレコードに、更新される前の行の内容を再構築するために必要な情報が含まれます。 6 バイトの DB_ROW_ID
フィールドには、新しい行が挿入されると単調に増加する行 ID が含まれています。 InnoDB
によって自動生成されたクラスタ化されたインデックスには、行 ID 値が含まれます。 それ以外の場合、インデックスに DB_ROW_ID
カラムが含まれることはありません。
ロールバックセグメント内の Undo ログは、挿入および更新 Undo ログに分割されます。 挿入 Undo ログはトランザクションロールバックでのみ必要であるため、トランザクションのコミット直後に破棄できます。 更新 Undo ログも一貫性読み取りで使用されますが、InnoDB
によってスナップショットが割り当てられたトランザクションが存在しなくなったあとでのみ破棄できます。更新 Undo ログ内のスナップショット情報は、データベース行の以前のバージョンを構築する際に一貫性読み取りで必要となる可能性があります。
トランザクション (一貫性読み取りのみを発行するトランザクションを含む) を定期的にコミットしてください。 それ以外の場合は、InnoDB
は更新 Undo ログからデータを破棄できないため、ロールバックセグメントが大きくなり過ぎてテーブルスペースがいっぱいになる可能性があります。
一般に、ロールバックセグメント内の Undo ログレコードの物理的サイズは、それに対応する挿入された行や更新された行よりも小さいです。 この情報を使用すると、ロールバックセグメントで必要となる領域を計算できます。
InnoDB
マルチバージョンスキームでは、SQL ステートメントで行を削除しても、その行はすぐにデータベースから物理的に削除されません。 InnoDB
は、削除用に書き込まれた更新 Undo ログレコードが破棄されたときにのみ、対応する行およびそのインデックスレコードを物理的に削除します。 このような削除操作はパージと呼ばれ、非常に高速です。通常は、削除が行われなかった SQL ステートメントと同じ時系列順で実行されます。
テーブル内で小さめのバッチの行をほぼ同じ速度で挿入および削除すると、すべての「デッド」行が原因で、パージスレッドが遅延し始め、増加し続ける可能性があります。これにより、すべてにおいてディスクが抑制され、非常に低速になります。 このような場合は、新たな行操作を抑制し、innodb_max_purge_lag
システム変数を調整することで、より多くのリソースをパージスレッドに割り当てます。 詳細は、セクション15.14「InnoDB の起動オプションおよびシステム変数」を参照してください。
InnoDB
multiversion concurrency control (MVCC) は、セカンダリインデックスをクラスタ化されたインデックスとは異なる方法で扱います。 クラスタ化されたインデックス内のレコードはインプレースで更新され、非表示のシステムカラムは undo ログエントリを指し、このエントリから以前のバージョンのレコードを再構築できます。 クラスタ化されたインデックスレコードとは異なり、セカンダリインデックスレコードには非表示のシステムカラムは含まれず、インプレースで更新されません。
セカンダリインデックスカラムが更新されると、古いセカンダリインデックスレコードが削除マークされ、新しいレコードが挿入され、削除マークが付けられたレコードが最終的にパージされます。 セカンダリインデックスレコードが削除マークされるか、新しいトランザクションによってセカンダリインデックスページが更新されると、InnoDB
はクラスタインデックスでデータベースレコードを検索します。 クラスタインデックスでは、読取りトランザクションの開始後にレコードが変更された場合、レコード DB_TRX_ID
がチェックされ、正しいバージョンのレコードが undo ログから取得されます。
セカンダリインデックスレコードが削除対象としてマークされている場合、またはセカンダリインデックスページが新しいトランザクションによって更新されている場合、covering index 手法は使用されません。 InnoDB
は、インデックス構造から値を戻すかわりに、クラスタ化されたインデックス内のレコードを検索します。
ただし、index condition pushdown (ICP) の最適化が有効で、WHERE
条件の一部をインデックスのフィールドのみを使用して評価できる場合、MySQL サーバーは WHERE
条件のこの部分を、インデックスを使用して評価されるストレージエンジンにプッシュダウンします。 一致するレコードが見つからない場合、クラスタインデックスルックアップは回避されます。 一致するレコードが見つかった場合、削除マークが付けられたレコードの中でも、InnoDB
はクラスタ化されたインデックス内のレコードを検索します。