列アドレス:
記事ディレクトリ
1.全体的なアーキテクチャ
InnoDBストレージエンジンの構造は、主にメモリ構造とディスク構造の2つの部分に分かれており、前者はMySQLのプロセスにあり、後者はファイルシステムにあります。さらに、メモリ内のデータを更新する一連のバックグラウンドスレッドがあります。
メモリ構造には、主に次のものが含まれます。
- バッファプール
- バッファを変更
- アダプティブハッシュインデックス
- ログバッファ
1.1メモリ構造
1.1.1バッファプール
InnoDBはメモリを使用して、データベース全体のパフォーマンスに対するハードディスク速度の影響を補正します。バッファー・プールのデータ・ページ・タイプには、索引ページ、データ・ページ、取り消しページ、変更バッファー書き込みキャッシュ、およびその他の情報が含まれます。InnoDBがページを読み取って変更すると、最初にキャッシュ内のページを変更しようとすると同時に、REDOログとチェックポイントメカニズムを使用してダーティページをディスクに非同期にフラッシュします。
MySQLサーバーでは、メモリの最大70%〜80%が一般にInnoDBキャッシュに使用されます。
バッファープールのLRUアルゴリズム
キャッシュプール内のページは主に、クエリによって読み取られたページとバックグラウンドスレッドによって先読みされたページ、および最適化されたLRU(Least Recently Used)アルゴリズムがキャッシュページの管理に使用されます。
従来のLRUアルゴリズムでは、新しく追加されたデータはリンクリストの先頭に配置され、最後の容量を超えるデータは削除されます。リンクされたリストのデータがヒットしたら、それを先頭に移動します。このようにして、最後にアクセスされたデータと最も頻繁にアクセスされたデータがリンクリストの先頭にあることが保証され、最も使用頻度の低いデータが最初に削除されます。しかし、その主な欠点は、先読みの無効化とバッファープールの汚染の問題を解決できないことです。
- 先読みエラー
先読みページにアクセスしていないため、できるだけ早くLRUリストから削除する必要があります。 - バッファプールの汚染
一部のSQLは多数の行をスキャンし、バッファプール内のほとんどまたはすべてのページを置き換える場合があります。そして、これらのページはこのクエリでのみ必要になる場合があり、ホットデータは置き換えられます。バッファプールのパフォーマンスが急激に低下します。
InnoDBバッファープールはミッドポイントを導入します。ミッドポイントは、LRUリストを新しいサブリスト(若い領域)と古いサブリスト(古い領域)に分割します。これらはデフォルトでスペースの5/8および3/8を占めます。新しく追加されたページはミッドポイントに配置されます。このページにアクセスし、古いサブリストの滞在時間がしきい値(デフォルトは1秒)を超えると、新しいサブリストの先頭に昇格します。同時に、新しいサブリストの最後のデータページが古いサブリストに圧縮されます。これは、ページが古くなると呼ばれます。最終的に、古いサブリストの最後の容量を超えるデータページは、最終的に削除されます。このようにして、事前に読み取られた無効なページとバッファープールの汚染を引き起こすページは、古いサブリストにのみ残り、新しいサブリストの実際のホットデータは置き換えられません。
先読みInnoDBは、事前にバッファープールにアクセスされる可能性があるページを非同期で読み取ります。先読みは、線形先読みとランダム先読みに分けられます。線形先読みは次の領域のページをバッファープールに読み取り、ランダム先読みは現在の領域の残りのページをバッファープールに読み取ります。
ダーティページの更新
InnoDBは、次の状況でキャッシュプールのダーティページをディスクにフラッシュします。
- システムがアイドル状態のとき
- バッファプールが不足している場合
- REDOログ領域が不十分な場合、
ページクリーナスレッドがダーティページの更新を担当します。
1.1.2バッファー書き込みキャッシュの変更
InnoDBは、バッファープールのバッファープールを使用してデータページのアクセス速度を加速します。データページへの変更も最初にバッファープールで更新され、その後、ダーティページが適切なタイミングで更新されます。変更されるページがキャッシュにない場合、ページが最初にディスクからキャッシュプールに読み込まれ、その後変更されると、ランダムIOオーバーヘッドが高くなります。このため、InnoDBは変更バッファーを導入して、補助インデックス(セカンダリインデックス)の操作をキャッシュし、ランダム読み取りIOを削減して、操作統合の効果を実現します。
たとえば、補助インデックスのリーフノードを更新する必要がある場合、
- データページがキャッシュプールにある場合、キャッシュ内のページは直接更新され、ダーティページが更新されます。
- データページはバッファープールにありません。InnoDBはこれらの操作を変更バッファーにキャッシュし、データページが次に読み込まれるときにマージ操作を実行します。
変更バッファーは、挿入、更新、および削除操作をサポートします。これは、バッファープールに存在するだけでなく、システムのテーブルスペースにも格納されます(通常のB +ツリーの方法で)。キャッシュされるオブジェクトは次のとおりです。
- 通常の補助インデックスリーフノード、クラスター化インデックスは使用できません(PS:クラスター化インデックスの挿入は通常、順次IOです)。
- 一意のインデックスの削除操作では、一意性を判断するためにデータページをクエリする必要があるため、挿入操作はキャッシュできません。
マージ
変更バッファ内の操作を対応するデータページに適用する操作をマージと呼びます。トリガーのタイミングは次のとおりです。
- クエリが対応するデータページにアクセスした
- マスタースレッドは定期的にマージ操作を実行します
マージの実行フロー:
- 元のデータページをディスクからバッファープールに読み取ります。
- 変更バッファからデータページの変更バッファレコードを検索します。複数のレコードが存在する可能性があり、それらを順番に適用します
- データページの変更とバッファの変更の変更を含む、REDOログの書き込み
- 後続のダーティページの更新
シーンに適応
同じデータページに蓄積される操作が多いほど、変更バッファー操作と統合の利益が大きくなります。これは主に、課金アプリケーションやログアプリケーションなど、書き込みの直後にアクセスされるデータページの確率が比較的小さい、書き込みが多く読み取りが少ないシナリオに適用されます。逆に、ビジネスの更新モードが書き込み直後にクエリを実行する場合、ランダムIOの数は減少しませんが、変更バッファーのメンテナンスコストは増加します。
バッファクラッシュリカバリの変更
トランザクションがコミットされると、変更バッファ内の操作がREDOログに記録され、予期しない障害が発生した後、REDOログをクラッシュリカバリに使用できます。
バッファー構造図の変更
バッファーマインドマップの変更
1.1.3アダプティブハッシュインデックスAHI
一般に、B +ツリーの高さは2〜4レイヤーであるため、ターゲットデータページを見つけるには2〜4倍のIOが必要です。たとえば、デフォルトの自動インクリメント主キーを使用して、各レコードが1KBの場合、3レベルのクラスター化インデックスB +ツリーは約2,000万のデータを格納できます。ハッシュインデックスの時間の複雑さはO(1)であり、通常、データの検索に必要なIOは1つだけです。
繰り返しパスファインディングのオーバーヘッドを削減するために、InnoDBはアクセスモード(クエリ条件)と頻度に従ってホットページのハッシュインデックスを自動的に作成し、リーフノードをすばやく見つけます。キーはクエリ条件のインデックスの最初のN列で構成され、値はリーフノードの位置です。AHIはメモリ構造であり、インデックスのインデックスと見なすことができます。
AHIを確立する前提は次のとおりです。
- ページへの同じ連続アクセスパターン
- このモードでのページアクセス数が特定のしきい値に達しました
AHIの適応シナリオ:
- 同等のクエリ
- クエリ条件のプレフィックスインデックスの列数がAHIの列数より大きい
同時実行性が高い場合、AHIは競争力のあるリソースになる可能性があります。クエリモードでAHIを利用できない場合は、AHIをオフにして、不要なパフォーマンスオーバーヘッドを減らすことを検討してください。
1.2.4ログバッファ
ログバッファーは、主にREDOログREDOログをキャッシュします。通常、ログを大きく設定する必要はありません。マスタースレッドは1秒ごとにREDOログを配置し、トランザクションがコミットされたとき、またはログバッファースペースが小さすぎるときにログを更新します。
詳細については、ログシステムの章を参照してください
1.2ハードディスク構造
ハードディスクに保存されている主な構造は次のとおりです。
- テーブルスペース
- システムテーブルスペース(共有テーブルスペース):データディクショナリ、二重書き込みバッファー、変更バッファー、ログの取り消し
- 排他的なテーブルスペース:各テーブルのデータとインデックスを格納します
- undo tablespace:undo tablespaceには、undoログのundoレコードのコレクションが含まれています
- 一時表スペース:ユーザーが作成した一時表
- REDOログ
データベースが予期せず停止した場合、InnoDBストレージエンジンは障害復旧にREDOログを使用します。InnoDBストレージエンジンには少なくとも1つのREDOログファイルグループがあり、各グループには少なくとも2つのREDOログがあります。各ロググループREDOログファイルは同じサイズで、循環追加書き込みモードで実行されます。
詳細は事務の章をご覧ください
1.3バックグラウンドスレッド
InnoDBストレージエンジンはマルチスレッドアーキテクチャであり、そのバックグラウンドスレッドには主に、マスタースレッド、IOスレッド、ページクリーナースレッド、パージスレッドが含まれます。
1.3.1マスタースレッド
InnoDBの主な作業はマスタースレッドで行われ、そのスレッドの優先度が最も高くなります。マスタースレッド内には複数のループがあります。メインループ、バックグラウンドループ、リフレッシュループ、一時停止ループです。その主なタスクは次のとおりです。
- ログブラッシングのやり直し
- マージ変更バッファー(マージされた書き込みバッファー)
ページクリーナスレッドとパージスレッドは、ダーティページの更新とページリサイクルの取り消しを担当します。
1.3.2 IOスレッド
InnoDBは多くのAIOを使用します。IOスレッドの主な仕事は、このIO要求のコールバックを処理することです。
- スレッドを書く
- スレッドを読む
- バッファスレッドの挿入
- ログスレッド
各タイプのIOスレッドには複数のタイプがあります。
1.3.3ページクリーナースレッド
ページクリーナースレッドは、主にバッファープール内のダーティページをディスクにフラッシュする役割を果たします。
1.3.4スレッドのパージ
アンドゥログページとデータページスペースの回復を担当します。
InnoDBはMVCCをサポートしているため、レコードの削除、元に戻すログのリカバリなどをすぐに実行することはできませんが、これらの古いバージョンがトランザクションによって参照されていない場合は、クリーンアップ操作を実行する必要があります。
更新取り消しログは履歴リストに順番に配置され、バックグラウンドのパージスレッドが定期的にスキャンして、不要な取り消しログをクリーンアップします。さらに、削除済みとしてマークされた行レコード(削除フラグ)は完全に削除されます。つまり、レコードが占めるスペースは、再利用のためにPAGE_FREEリンクリストに配置されます。
元に戻すログを挿入します。これは現在のトランザクションに対してのみ有効であるため、トランザクションがコミットされた直後に削除操作を行わなくても削除できます。
2. InnoDBの主要テクノロジー
InnoDBの主要なテクノロジーには、主に次の5つが含まれます。
- バッファを変更
- 二重書き込み2回
- アダプティブハッシュインデックス
- 非同期IO非同期IO
- フラッシュネイバーページ
2.1二重書き込み
二重書き込みは、主にデータページの信頼性を向上させ、部分的な書き込みエラーによるデータの損失を防ぐためのものです。InnoDBデータページは通常16Kであり、ファイルシステムページサイズは4Kであるため、オペレーティングシステムはInnoDBデータページのアトミックな書き込みを保証できない場合があります。ページの更新処理中にサーバーがダウンすると、元のデータページが破損します。REDOログはデータ・ページでの変更操作を記録するため、REDOログを再生しても部分的な書き込み障害の問題を解決できません。データ・ページ自体が破損している場合、REDOログの変更をそれに適用しても意味がありません。
InnoDBのソリューションは、データページのコピー、つまりDouble Writeです。ダーティページを更新する必要がある場合、Doube Writeのメインフローは次のとおりです。
- まず、バッファプールのダーティページを二重書き込みバッファにコピーします。
- ダブルライトバッファ順追加書かれた方法でリアルタイムブラシディスク(システムテーブルスペース)、同期IO。
- 次に、二重書き込みバッファーのページを対応するテーブルスペースに書き込みます。これは、現時点ではランダムIOと非同期IOです。整合性チェックは、非同期IOコールバック関数で実行されます。
二重書き込みバッファはメモリ内に存在するだけでなく、メモリ/ディスクの2層構造です。
部分的な書き込み障害が発生すると、システムテーブルスペースのダブルライトバッファーを介して回復できます。その後、REDOログを適用して、完全な障害回復プロセスを完了します。
ファイルシステムがページサイズのアトミックな書き込みを提供でき、部分的な書き込みエラーを防ぐソリューションを提供できる場合は、二重書き込みをオフにすることができます。
2.2非同期IO
InnoDBはAIOを使用してディスク操作のパフォーマンスを向上させ、IOマージ操作を実行して、複数のIO操作を1つのIO操作に結合します。
2.3フラッシュネイバーページ
InnoDBがダーティページを更新すると、ページが配置されている領域の下のすべてのページが検出されます。ダーティページでもある場合は、それらも一緒に更新します。これにより、IOの数を減らすことができます。ただし、次のような場合があります。
- それほど汚れていないページを更新すると、ページはすぐに再び汚れる
- SSDはシャットダウンを検討できますか
参照
InnoDBストレージエンジン—MySQL公式ウェブサイト
「MySQLテクニカルインサイダー(InnoDBストレージエンジン)」
「MySQL実際の戦闘に関する45の講義」オタク時間
「InnoDBアーキテクチャ、画像は数秒で理解できます!》 WeChat 公式アカウント -Architect's Road
InnoDBキャッシュプール