マスタースレッド
- 前回のInnoDBアーキテクチャの導入により、InnoDBストレージエンジンの主な作業が別のバックグラウンドスレッドであるマスタースレッドで完了することがわかりました。この記事では、スレッドの特定の実装とスレッドで発生する可能性のある問題を紹介します。
1. InnoDB1.0.xより前のマスタースレッド
- マスタースレッドのスレッド優先度は最高です。その内部は複数のループで構成されています:
- メインループ(ループ)、バックグラウンドループ(バックグラウンドループ)、リフレッシュループ(フラッシュループ)、サスペンドループ(サスペンドループ)
- マスタースレッドは、実行中のデータベースの状態に応じてさまざまなサイクルを切り替えます
メインループ(ループ)
- 操作のほとんどは、このループであるため、ループは、メインループと呼ばれる二つの主要な事業を展開しています-操作毎秒や操作ごとに10秒
- 擬似コードは次のとおりです。次のように表示されます。
- ループループはスレッドスリープによって実装されます。つまり、いわゆる1秒に1回、または10秒に1回の操作は正確ではありません。重い負荷の場合には、そこに遅延することができる、それだけでは、この周波数についてであるということができます。もちろん、この頻度を確保するために、InnoDBソースコードでは他の方法が採用されています
- 1秒あたりの操作は次のとおりです。
- ①トランザクションがまだコミットされていない場合でも(常に)、ログバッファはディスクにフラッシュされます。
- トランザクションがまだコミットされていない場合でも、InnoDBはREDOログバッファーの内容を毎秒REDOログファイルにフラッシュします。大規模なトランザクションのコミット時間も非常に短い理由をよく説明できるため、これは知っておく必要があります。
- ②挿入バッファをマージする(可能):
- マージ挿入バッファー(Insert Buffer)は毎秒発生しません。InnoDBは、現在の1秒間に発生したIOの数が5回未満であるかどうかを判断します。5回未満の場合、InnoDBは、現在のIO圧力が非常に小さいと見なし、マージ挿入バッファーの操作を実行できます。
- ③InnoDBバッファプール内の最大100個のダーティページをディスクにフラッシュします(おそらく):
- 100個のダーティページの更新が毎秒行われるわけではありません。InnoDBは、現在のバッファープール(buf_get_modified_ratio_pct)のダーティページの比率が構成ファイルのinnodb_max_dirty_pages_pctパラメーター(デフォルトは90、90%を表す)を超えているかどうかを判断します。このしきい値を超えると、InnoDBはディスク同期操作が必要であると判断します。および100ページのダーティページディスクへのページ書き込み
- ④現在ユーザーアクティビティがない場合は、バックグラウンドループに切り替えます(おそらく):
- 1秒に1回の操作によると、メインループの擬似コードは次のように具体化されます。
- 10秒ごとの操作は次のとおりです。
- ①汚れた100ページをディスクにフラッシュします(可能な場合)
- InnoDBは、最初に、過去10秒間にディスクIO操作が200回未満であるかどうかを判断します。そうである場合、InnoDBは、十分なディスクIO操作容量があると判断し、100個のダーティページをディスクにフラッシュします。
- ②最大5つの挿入バッファをマージします(常に)
- InnoDBは挿入バッファーをマージします。1秒に1回の操作で発生する可能性のあるマージ挿入バッファー操作とは異なり、このマージ挿入バッファー操作は常にこの段階で実行されます。
- ③ログバッファをディスクにフラッシュする(常に)
- InnoDBは、ログバッファをディスクに再度フラッシュします。これは、1秒に1回発生する操作と同じです。
- ④無駄な元に戻すページを削除する(常に)
- InnoDBは、「フルパージ」クリーンアップ操作を実行して、不要な元に戻すページを削除します
- テーブルに対して更新や削除などの操作を実行すると、元の行は削除済みとしてマークされますが、読み取り関係が一貫しているため、これらの行バージョンの情報を保持する必要があります。ただし、完全なパージプロセスでは、InnoDBは、現在のトランザクションシステムで削除された行を削除できるかどうかを判断します。たとえば、以前のバージョンの元に戻す情報を読み取る必要があるクエリ操作がある場合があります。削除できる場合は、 InnoDBはすぐに削除します
- ソースコードから、InnoDBが完全なパージ操作を実行すると、毎回最大20の元に戻すページを回復しようとすることがわかります。
- ⑤100または10ページのダーティページをディスクにフラッシュします(常に)
- InnoDBは、バッファープール(buf_get_modified_ratio_pct)内のダーティページの比率を決定します。ダーティページが70%を超える場合、100個のダーティページがディスクにフラッシュされます。ダーティページの比率が70%未満の場合のみ、ダーティページの10%をフラッシュする必要があります。ディスクに
- 上記のすべての手順により、メインループの擬似コードを次の形式に縮小できます。
バックグラウンドループ
- 場合はユーザーのアクティビティがない(データベースがアイドル状態のとき)、またはデータベースがシャットダウンされる(シャットダウン)、それがこのサイクルに切り替わります
- バックグラウンドループは次の操作を実行します。
- 不要な元に戻すページを削除する(常に)
- 20個の挿入バッファーを組み合わせる(常に)
- メインループに戻る(常に)
- 条件が満たされるまで100ページを更新し続けます(おそらく、フラッシュループにジャンプして完了します)
ループを一時停止します
- フラッシュループで何もすることがない場合、InnoDBはサスペンドループに切り替え、マスタースレッドをサスペンドし、イベントが発生するのを待ちます。
- ユーザーがInnoDBストレージエンジンを有効化(有効化)しているが、InnoDBストレージエンジンテーブルを使用していない場合、マスタースレッドは常に一時停止状態になります
- 最後に、マスタースレッドの完全な擬似コードは次のとおりです。
2. InnoDB1.2.xより前のマスタースレッド
InnoDB1.0.xより前の欠陥
- 上記のInnoDB1.0.xより前のコンテンツの紹介から、InnoDBには実際にIOに制限があることがわかります。実際、バッファープールがディスクにフラッシュされるときに、ハードコーディングが行われます。今日、ディスクテクノロジの急速な発展に伴い、ソリッドステートディスク(SSD)が登場すると、この種の規制により、ディスクIOでのInnoDBのパフォーマンス、特に書き込みパフォーマンスが大幅に制限されました。
- 前の擬似コードからわかるように、InnoDBは最大100個のダーティページのみをディスクにフラッシュし、20個の挿入バッファーをマージします。書き込みが集中するアプリケーションの場合、1秒あたり100を超えるダーティページが生成される可能性があり、20を超える挿入バッファが生成されると、マスタースレッドが「ビジーすぎる」か、常に実行されます。非常に低速です。ハードコーディングにより、ディスクが1秒以内に100ページを超えるページと20の挿入バッファーのマージを処理できる場合でも、マスタースレッドは100のダーティページをフラッシュし、20の挿入バッファーをマージすることのみを選択します。同時に、多くのデータがディスクにフラッシュバックされていないためにダウンタイムを復元する必要がある場合、特に挿入バッファーの場合、回復に時間がかかることがあります。
- これらの質問は、もともとGoogleのエンジニアであるMarkCallaghanによって尋ねられました。
innodb_io_capacityパラメーター
- 上記の問題に対応して、InnoDBの担当者は修正を行い、パッチを発行しました。InnoDB開発チームはGoogleのパッチを参照し、問題を修正するための同様の方法を提供しました。
- InnoDBプラグインは、特定のディスクIOを示すために使用されるパラメーター(InnoDB 1.0.x以降)innodb_io_capacityを提供します。デフォルト値は200です。ディスクにフラッシュされるページ数は、innodb_io_capacityのパーセンテージに従って制御されます。ルールは次のとおりです。
- 挿入バッファーをマージする場合、マージ挿入バッファーの数はinnodb_io_capacityの値の5%です。
- バッファからダーティページをフラッシュする場合、フラッシュされるダーティページの数はinnodb_io_capacityです。
show variables like 'innodb_io_capacity'\G;
- ユーザーがSSDタイプのディスクを使用する場合、または複数のディスクをRAIDとして使用する場合、ストレージデバイスのIO速度が速いと、ディスクIOのスループット位置に達するまでinnodb_io_capacityの値を高く調整できます。
innodb_max_dirty_pages_pctのデフォルト値に問題があります
- innodb_max_dirty_pages_pctは前の記事で紹介されました。https : //blog.csdn.net/m0_46405589/article/details/113861431を参照してください。
- 以下の写真は前の記事から取られたもので、innodb_max_dirty_pages_pctの紹介は次のとおりです。
- InnoDB1.0.xより前では、この値のデフォルト値は90です。これは、チェックポイントを設定する前に、ダーティページがバッファプールの90%を占めることを意味します。ただし、この値は「大きすぎます」。これは、InnoDBストレージエンジンがバッファープールとフラッシュループを毎秒更新するときにこの値を判断するためです。値がinnodb_max_dirty_pages_pctより大きい場合、100個のダーティページのみが更新されます。メモリまたはデータベースの容量サーバーは大きなプレッシャーにさらされており、代わりにダーティページの更新速度が低下します。同様に、データベースのリカバリノードではさらに時間がかかる場合があります
- 多くのフォーラムでこの問題に関する議論があります。この値を20または10に調整する人もいます。ただし、実験によると、innodb_max_dirty_pages_pctを20または10に調整すると、ディスクの負荷が高まり、システムの負担が増大します。Googleはこの問題についてテストを実施し、20が最適値ではないことを証明しました。Innodb 1.0.x以降、innodb_max_dirty_pages_pctのデフォルト値は75になりました。これは、Googleがテストした80に近い値であり、ダーティページの更新頻度を高め、ディスクIOの負荷を確保できます。
innodb_adaptive_flushing参数
- innodb_adaptive_flushing(アダプティブフラッシュ)は、InnoDB 1.0.xバージョンによってもたらされる別のパラメーターです。この値は、1秒あたりに更新されるダーティページの数に影響します。
- このパラメータはデフォルトでオフになっています
- 元の更新ルールは次のとおりです。
- バッファープール内のダーティページの割合がinnodb_max_dirty_pages_pct未満の場合、ダーティページは更新されません
- innodb_max_dirty_pages_pctより大きい場合、100個のダーティページを更新します
- innodb_adaptive_flushingパラメーターの導入により、InnoDBストレージエンジンは「buf_flush_get_desired_flush_rate」と呼ばれる関数を使用して、フラッシュする必要のあるダーティページの最適な数を決定します。ソースコードを大まかに読んだ後、この関数は、REDOログの生成速度を判断することにより、更新するダーティページの最適な数を決定することがわかりました。したがって、ダーティページの割合がinnodb_max_dirty_pages_pct未満の場合、一定量のダーティページも更新されます
show variables like 'innodb_adaptive_flushing'\G;
innodb_purde_batch_sizeパラメーター
- 各完全パージ操作の前に、最大20の元に戻すページが復元されます(上記のメインループで導入)
- InnoDB 1.0.xバージョン以降、パラメーターinnodb_purde_batch_sizeが導入されました。これにより、完全なパージごとに再利用される元に戻すページの数を制御できます。
- このパラメータのデフォルト値は20で、動的に変更できます
show variables like 'innodb_purde_batch_size'\G;
マスタースレッドのステータスを表示する
- InnoDB 1.0.x以降、次のコマンドの情報から現在のマスタースレッド情報を表示できます。
- メインループは1回実行されました
- サスペンド(スリープ)の操作は1秒間に1回実行されました
- 10秒のイベントは10回行われました
- バックグラウンドループは1回実行されました
- フラッシュループも1回実行されます
show engine innodb status\G;
- 注:データベースの負荷圧力が低い場合、1_secondとsleepsの値は等しくなければなりません。しかし、負荷圧力がある場合、2つは等しくありません。通常、この2つの差は、現在のデータベースの負荷圧力を反映するために使用されます。
- InnoDB 1.0.xバージョンから、マスタースレッドの擬似コードが変更され、最終的に次のようになります。
3、マスタースレッドのInnoDB1.2.xバージョン
- InnoDBの1.2.xのバージョンでは、マスタースレッドは再び最適化されており、そしてマスタースレッドがパフォーマンスに重要な役割を果たしていることがわかります
- InnoDB 1.2.xバージョンでは、MastertThreadの擬似コードは次のとおりです。
- srv_master_do_idle_tasks():上記の10秒ごとの操作です
- srv_master_do_active_tasks(): 1秒あたりの前の操作です
- ダーティページを更新する操作の場合:マスタースレッドスレッドから別のページクリーナースレッドに分離することで、マスタースレッドの作業を減らし、システムの同時実行性をさらに向上させます。