MySQL のデータベース バッファ プール (バッファ プール) について理解します。

青灯夜游
リリース: 2023-02-21 19:44:06
転載
2326 人が閲覧しました

MySQL のデータベース バッファ プール (バッファ プール) について理解します。

InnoDB ストレージ エンジンを使用するテーブルの場合、メモリとディスク間のスワップインおよびスワップアウトの基本粒度として、ストレージ スペースがページ単位で管理されます。ページをディスクからメモリにロードすると、ディスク I/O が実行されます。ディスク I/O のオーバーヘッドは全体のパフォーマンスに大きく影響しますが、対応するページをメモリから直接読み込めば、ディスク I/O によるパフォーマンスの低下が軽減され、効率が大幅に向上するのではないでしょうか。これを踏まえて、Buffer Pool (Buffer Pool) が登場したので、次は InnoDB の Buffer Pool について説明します。

バッファ プール

バッファ プールは非常に優れているので、すべてのデータをバッファ プールに保存すればよいのではないかと考える人もいるかもしれません。いいえ、いいえ、バッファ プールは、オペレーティング システムによって割り当てられる連続したメモリです。メモリはディスクに比べて容量がはるかに小さく、高価です。それでは、オペレーティング システムはバッファ プールにどれだけのメモリを割り当てるのでしょうか?

  • デフォルトでは、バッファ プールのサイズは 128MB です;

もちろん、マシンのメモリ容量が非常に大きい場合は、起動オプション パラメータを構成できます。構成ファイル innodb_buffer_pool_size の単位は bytes で、最小値は 5MB 未満にすることはできません。

バッファ プールの内部構造

バッファ プールは、オペレーティング システムによって割り当てられた連続メモリを、デフォルト サイズ 16KB の複数のページ (バッファ ページ) に分割します [現時点では、ディスク ページはバッファ プールにキャッシュされます] ページをディスクからバッファ プールにスワップするとき、その場所はどのように割り当てられますか?そのため、これらのバッファプール内のバッファページを識別するための制御情報が必要となり、この制御情報はコントロールブロックと呼ばれるメモリ領域に格納され、バッファページと1対1に対応している。制御ブロックのサイズも固定です。したがって、この連続したメモリ空間では、必然的にメモリの断片化が発生します。要約すると、バッファ プールの内部構造は次のようになります。

  • バッファ ページ
  • 制御ブロック: ページ番号、バッファ プール内のバッファ ページのアドレス、リンク リスト ノード情報など
  • メモリの断片化 [メモリが適切に割り当てられている場合、メモリの断片化は不要です]

MySQL のデータベース バッファ プール (バッファ プール) について理解します。

バッファ プールの管理

上記のリンク先リストノード情報は制御ブロックに記載されていますが、リンクリストノードは何に使用されるのでしょうか?これは、バッファー プール内のページをより適切に管理するためです。制御ブロックとバッファ ページの間には 1 対 1 の対応があるため、リンク リストは制御ブロックをリンクするために使用されます。

1) フリー リンク リスト

すべてのフリー バッファ ページに対応するコントロール ブロックをリンクして、リンク リストを形成します。

問題の解決策: ページをディスクからバッファー プールにスワップするとき、バッファー プール内のどのページが空いているかを識別するにはどうすればよいですか?フリー リンク リストでは、ディスク ページがバッファ プールにスワップされると、フリー リンク リストから直接フリー バッファ ページが取得され、ディスク ページ内の対応する情報がバッファ ページに対応する制御ブロックに埋められます。そして、フリーリンクリストからコントロールブロックを削除するだけです。

2) リンク リストの更新

バッファ プール内のバッファ ページのデータが変更され、ディスク上のデータと不整合が生じた場合、そのページはダーティ ページと呼ばれます。 。すべてのダーティ ページに対応する制御ブロックをリンクして更新リンク リストを形成し、このリンク リストに基づいて将来のある時点で対応するキャッシュ ページのデータをディスクにリフレッシュします。

3) LRU リンク リスト

バッファ プールのサイズには制限があり、キャッシュされたページがバッファ プールのサイズを超える場合、つまり、空きバッファ ページがありません。追加される新しいページです。バッファ プールに入るとき、LRU 戦略が採用され、バッファ プールから古いバッファ ページが削除されてから、新しいページが追加されます。 LRU リンクリストは内容が多いので、次回は別途紹介します。

LRUリンクリストに含まれる「理念」

まずは先読みの仕組みについて触れておきます

I/Oの最適化の仕組みその名の通り、これらのページはバッファ プールにロードされ、すぐに必要になることが予想されます。これらのリクエストでは、範囲内のすべてのページが導入されます。これは、いわゆる ローカリティ原則 . 目的は、ディスク I/O を削減することです。

先読みメカニズムを理解する前に、InnoDB の論理ストレージ ユニット (テーブルスペース → セグメント → エクステント → ページ) を確認してみましょう。後で使用する領域について具体的に説明します。領域は、物理的な場所で連続した 64 ページ です。つまり、領域のサイズは 1MB です。

MySQL のデータベース バッファ プール (バッファ プール) について理解します。

先読みメカニズムは、次の 2 つのタイプに細分できます。

  • 線形先読み: バッファ プール内で順次アクセスされるページに基づいて、どのページがすぐに必要になるかを予測する手法。 innodb_read_ahead_threshold パラメータを設定すると、連続してアクセスされる特定の領域のページがこのパラメータの値を超えると、非同期読み取りリクエストがトリガーされ、次の領域のすべてのページがバッファ プールに読み込まれます。
  • ランダム先読み: ページが読み取られる順序に関係なく、バッファ プール内にすでにあるページに基づいて、ページがいつ必要になるかを予測できます。同じエクステントの連続した 13 ページがバッファ プール内で見つかった場合、InnoDB はエクステントの残りのページをプリフェッチするリクエストを非同期的に発行します。ランダム読み取りは、変数 innodb_random_read_ahead を構成することで制御されます。
  • 従来の LRU はバッファ ページをどのように管理しますか?

LRU アルゴリズムを使用して、最も最近使用されていないバッファ ページを管理し、対応するリンク リストを形成して簡単に削除します。

ページがアクセスされると (つまり、最新のアクセスが)

ページがバッファー プール内にあると、対応する制御ブロックがリンクされた LRU の先頭に移動されます。 list
  • ページはバッファ プールにありません。バッファ プールでは、最後にある最も最近使用されていないページが削除され、そのページがディスクからロードされ、LRU リンク リストの先頭に配置されます
  • では、なぜ InnoDB はこのような直感的な LRU アルゴリズムを使用しないのでしょうか?理由は次のとおりです。

  1. 先読み失敗

    バッファ プールに先読みされたページは、LRU の先頭に配置されます。リンクされたリストですが、その多くはページが読み取れない可能性があります。

  2. バッファ プールの汚染

    低頻度のページをバッファ プールに多数読み込むと、高頻度のページがバッファから削除されます。プールから削除されます。 。たとえば、

    full table scan

  3. 最適化された LRU はバッファ ページをどのように管理しますか?

上記の欠点に基づいて、特定の最適化された方法では、従来の LRU リンク リストをホット データ エリア [若いエリア] とコールド データ エリア [古いエリア] の 2 つの部分に分割します。

ホットデータ領域 [若い領域]

: 使用頻度の高いバッファページ

  • コールドデータ領域 [古い領域] : 使用頻度の低い領域
  • 構造図は次のとおりです。
図に示すように、ホット データ領域とコールド データ領域はそれぞれ異なる割合を占めています。

innodb_old_blocks_pct オプションは、コールド データ領域の 割合を制御します。

#改良された LRU は、先読み障害の問題をどのようにより適切に解決できるでしょうか?

MySQL のデータベース バッファ プール (バッファ プール) について理解します。

ページが初めてバッファ プールにロードされると、コールド データ領域の末尾にある制御ブロックが最初に削除されます (つまり、対応するページが削除されます)。とすると、新しいページに対応するコントロールブロックが削除され、コールドデータ領域の先頭にブロックが配置されます。

ページがその後アクセスされない場合、そのページはコールド データ領域から徐々に削除されますが、通常、ホット データ領域内の頻繁にアクセスされるバッファ ページには影響しません。

  • 改良された LRU は、バッファ プール汚染の問題をどのように解決できるでしょうか?
  • 結論を先に話します。この問題は十分に最適化されていません。理由は次のとおりです [テーブル全体のスキャンを例に挙げます]:

A初めてアクセスしたページもコールドデータ領域の先頭に配置されますが、その後のアクセスではホットデータ領域の先頭に配置され、アクセス頻度の高いページも排除されます。

では、バッファプール汚染の問題を解決するにはどうすればよいでしょうか?

  • バッファ プールでは、コールド データ領域の時間ウィンドウ メカニズムが導入されています。つまり、ページへのその後のアクセスとページへの最初のアクセスの間の時間間隔が、指定されたウィンドウ値より大きい場合にのみ、コールドデータ領域からページが削除され、ホットデータ領域の先頭に移動します。ウィンドウ値が指定値より小さい場合、移動操作は実行されません。
同様に、ウィンドウ値は

innodb_old_blocks_time

パラメーター [単位 ms] で設定できます。デフォルトは 1000 ミリ秒で、1 秒を指定すると、テーブル全体のスキャンなどのほとんどの操作が除外されます。たとえば、テーブル全体のスキャン中、ページへの複数のアクセス間の時間間隔は 1 秒を超えることはありません。
  • バッファ プール VS クエリ キャッシュ
  • バッファ プールとクエリ キャッシュは同じものですか? →Not

バッファ プールは頻繁に使用されるデータを保存しようとします。MySQL がページ読み取り操作を実行するとき、最初にページがバッファ プール内にあるかどうかを判断します。存在する場合は、直接読み取られます。ページが存在しない場合、ページはメモリまたはディスクを介してバッファ プールに保存されてから読み取られます。

クエリ キャッシュとは、クエリ結果を事前にキャッシュし、次回実行することなく結果を直接取得できるようにすることです。 MySQL のクエリ キャッシュはクエリ プランをキャッシュするのではなく、クエリの対応する結果をキャッシュすることに注意してください。ヒット条件が厳しく、データテーブルが変更されるとクエリキャッシュが無効になるため、ヒット率が低くなります。

    [関連する推奨事項:
  • mysql ビデオ チュートリアル
  • ]

以上がMySQL のデータベース バッファ プール (バッファ プール) について理解します。の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:juejin.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
関連するチュートリアル
人気のおすすめ
最新のコース
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート