14.2.12 InnoDB マルチバージョン

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 システム変数を調整することで、より多くのリソースをパージスレッドに割り当てます。詳細は、セクション14.12「InnoDB の起動オプションおよびシステム変数」を参照してください。


User Comments
Sign Up Login You must be logged in to post a comment.