MySQLのバッファプールの詳細な説明

MySQLのバッファプールの詳細な説明

MySQL のデータはディスクに書き込む必要があることは誰もが知っています。ディスクの読み取りと書き込みは、特にメモリと比較すると非常に遅くなります。ただし、通常 SQL を実行すると、書き込み操作と読み取り操作の両方で、予想ほど遅くなく、すぐに結果を得ることができます。

インデックスがあるから、当然インデックスがあった方が速いと言うかもしれません。しかし、インデックス ファイルもディスクに保存されるため、検索プロセスによってディスク I/O が生成されます。データ行に対して複数の操作を同時に実行すると、ディスク IO が何度も繰り返されるのではないでしょうか。

おそらくあなたも考えたことがあるでしょうが、データをメモリに保存するだけではだめなのでしょうか?メモリがディスクよりも高速であることは間違いありません。そうです、それではどうやって保存するのでしょうか? これが今日お話しするトピック、つまりバッファ プールです。

読者の皆様、ぜひフォローしてくださいね〜

図:マインドマップ

バッファプールを使い始める

上で述べたように、行を操作する SQL を実行する場合、必ずしもディスク操作を直接実行できるとは限りません。少なくとも緩衝地帯はある。そうでなければ、毎回巣の奥深くまで行くのに誰が耐えられるだろうか。

ここでバッファ プールが登場します。簡単に言えば、メモリ領域です。その存在理由の 1 つは、毎回ディスクにアクセスすることを回避し、最も頻繁にアクセスされるデータをキャッシュに入れて、データのアクセス速度を向上させることです。

バッファプールの機能がわかったところで、バッファプールが MySQL アーキテクチャ全体の中でどのような位置を占めているかを見て、マクロ的に理解してみましょう。

内部コンポーネントを見てみましょう。バッファ プールには、データ ページとインデックス ページ以外にもいくつかの種類があります。

バッファプールの応用

バッファ プールについて理解できたので、SQL 実行におけるバッファ プールの役割について最も関心があるかもしれません。前回の記事では、SQL ステートメントの実行プロセスについて簡単に説明しましたが、バッファ プールに関連する問題については触れませんでした。この問題では、エントリ ポイントとして SQL を引き続き使用します。

SQL 文を実行すると、それが読み取り操作である場合、検索対象のデータが配置されているデータ ページがメモリ内にある場合に結果が返されます。それ以外の場合は、対応するデータ ページがメモリにロードされ、結果が返されます。

書き込み操作にも同じことが当てはまります。変更する行が配置されているデータ ページがメモリ内にある場合は、変更後に対応する結果が返されます (もちろん、後続の操作もあります)。存在しない場合は、行に対応するデータ ページがディスクからメモリに読み込まれ、変更されます。

さて、最初の質問に戻りましょう。ディスク操作は遅いのに、SQL 実行は遅くないのはなぜですか?おそらくあなたはもうそれを知っていると思います。

バッファ プールの存在により、ディスク I/O によって発生するオーバーヘッドが大幅に削減されます。操作対象となるデータ行が配置されているデータ ページがキャッシュ内に存在する場合は、ディスクから読み取る必要はありません。この方法では、実行後にすぐに結果を得ることができます。

バッファプールの事前読み取りメカニズム

ディスク I/O がなくなるか減少する限り、実行速度は自然に速くなることがわかります。では、データ ページのロードに伴う避けられないディスク I/O に対処するためのより良い方法はあるのでしょうか?避けられないのであれば、ディスク I/O の数を減らすことが常に選択肢になるのではないでしょうか?

これから説明するのは、MySQL の「先読み」という新機能です。これは、バッファ プールで複数のデータ ページを事前に読み取ることで、Innodb が I/O を最適化する方法です。ディスクの読み取りと書き込みはページ単位で行われるため(固定サイズのデータ​​として理解できます。たとえば、1 ページのデータは 16K です)、毎回少なくとも 1 ページのデータが読み取られます。次に読み取るデータがページ内にある場合は、ディスクから再度読み取る必要がないため、ディスク I/O が削減されます。

対応するページ サイズは、コマンド ラインで次のコマンドを実行すると確認できます。

バッファプールスペース管理

バッファ プールが流行っているのだから、すべてのデータをバッファ プールに入れたらどうかと思うかもしれません。この速度は本当に素晴らしいのですが、それをディスクに保存するのは、年老いた牛が荷車を引くのと同じくらい遅いです。

おい、兄弟、目を覚ませ。メモリの揮発性はさておき、バッファ プールにもサイズ制限がある。すると、また混乱してしまうかもしれません。バッファプールにはサイズ制限があるので、毎回読み取るデータページをどのように管理すればよいのでしょうか。他のデータ ページがスペースを占有しているので、私のスペースはどこにあるのでしょうか?

ここでは、バッファ プールのスペース管理について説明します。実際、バッファ プールの管理の重要な部分は、プール内のデータをどのように整理し、特定の戦略に従ってプール内のデータを削除して、プール内のデータが「オーバーフロー」しないようにしながら、よく使用されるデータがプール内に残るようにすることです。

従来のLRU除去法

バッファ プールは、従来の LRU 方式に基づいてキャッシュ ページを管理します。まず、LRU を使用してどのように管理されるかを見てみましょう。

LRU の正式名称は Least Recently Used で、中国語名は「least Recently Used」です。名前からすぐに分かります。

ここでは 2 つの状況があります。

(1)キャッシュページはすでにバッファプール内にある

この場合、対応するキャッシュ ページは、ディスクから読み取ったり、他のキャッシュ ページを削除したりすることなく、LRU リンク リストの先頭に配置されます。

下の図に示すように、アクセスするデータがページ 6 にある場合は、リンク リストの先頭にページ 6 を配置するだけです。この場合、キャッシュ ページは削除されません。

(2)キャッシュページがバッファプールに存在しない

キャッシュ ページはバッファ内にありません。このとき、対応するデータ ページをディスクから読み取り、リンク リストの先頭に配置し、末尾のキャッシュ ページを削除する必要があります。

下の図に示すように、アクセスするデータがページ 60 にあり、ページ 60 がバッファ プールにない場合は、それがロードされてリンク リストの先頭に配置され、末尾のキャッシュ ページ 17 は削除されます。

バッファプール内のキャッシュページを削除する方法はシンプルかつ満足できるものだと思いますか?しかし、いくつかの質問について考えてみましょう。

事前読み取りの失敗

上で、バッファ プールの先読みメカニズムによって隣接するデータ ページがプリロードされる可能性があることを説明しました。隣接する 2 つのデータ ページ 20 と 21 がロードされ、ページ番号 20 のキャッシュ ページのみがアクセスされ、他のキャッシュ ページはアクセスされないとします。このとき、両方のキャッシュ ページはリンク リストの先頭にありますが、この 2 つのキャッシュ ページをロードするために、末尾のキャッシュ ページが削除され、削除されたキャッシュ ページが頻繁にアクセスされます。この場合、事前読み取りが失敗し、バッファプールに事前ロードされたページにアクセスされません。これは不合理ではありませんか?

バッファプールの汚染
また、SQL 文を実行する際に、大量のデータをスキャンしたり、テーブル全体をスキャンしたりすると、大量のデータ ページがバッファー プールにロードされ、バッファー プール内の既存のページがすべて置き換えられるという状況もあります。この状況も不合理です。これはバッファプールの汚染であり、MySQL のパフォーマンスが大幅に低下する可能性があります。

ホットデータとコールドデータの分離

従来の LRU 方式では、バッファ プールのスペース管理要件を満たすことができないようです。そのため、Msyql は LRU に基づいてホット データとコールド データを分離するソリューションを設計しました。

つまり、LRU リンク リストは、ホット データ領域用とコールド データ領域用の 2 つの部分に分割されます。

データ ページが最初にバッファー プールにロードされると、コールド データ領域のリンク リストの先頭に配置されます。1 秒後 (innodb_old_blocks_time パラメータによって制御されます)、キャッシュ ページがアクセスされ、ホット データ領域のリンク リストの先頭に移動されます。

ホット データ領域に移動する前に 1 秒待たなければならないのはなぜかと疑問に思うかもしれません。考えてみてください。データ ページがコールド データ領域にロードされた直後にアクセスされ、二度とアクセスされない場合はどうなるでしょうか。これにより、ホットデータ領域が無駄になるのではないですか? 1 秒経ってもアクセスされない場合は、今後頻繁にアクセスされない可能性があるので、ホット バッファに移動する必要はありません。キャッシュ ページが不足している場合は、コールド データ領域からそれらを削除します。

別のケースでは、データ ページがすでにホット バッファー内にある場合、アクセスされる限り、キャッシュ ページはリンク リストの先頭に挿入されますか?言うまでもなく、それは無理だと思うに違いありません。ホット データ領域のキャッシュ ページは頻繁にアクセスされます。キャッシュ ページがアクセスされるたびにリンク リスト ヘッダーが挿入されると、ホット バッファー全体が非常に混乱した状態になります。その光景を想像してみてください。

では私たちは何をすべきでしょうか? MySQL では、ホット データ領域の最後の 3/4 は、アクセスされた後にのみリンク リストの先頭に移動されるように最適化されており、最初の 1/4 のキャッシュ ページはアクセスされた後に移動されません。

さて、バッファプールについては以上です。今回は、バッファ プールによって SQL 実行が高速化される理由と、バッファ プール領域の管理方法について説明しました。コメント欄での議論を歓迎します。

要約する

バッファプールの応用

バッファ プールは、ディスク I/O によるオーバーヘッドを大幅に削減します。データ行が操作されるデータ ページをバッファ プールにロードすることで、SQL の実行速度を向上させることができます。

バッファプールの事前読み取りメカニズム

ディスク I/O を削減するために、Innodb はバッファ プールで複数のデータ ページを事前に読み取ることによって最適化します。これを事前読み取りと呼びます。

バッファプールスペース管理

  • バッファ プールの従来の LRU 方式では、事前読み取りの失敗とバッファ プールの汚染という 2 つの状況が発生します。したがって、この従来の方法はバッファ プールのスペース管理には適していません。
  • Msyql は、LRU 方式の最適化に基づいて、ホット データとコールド データを分離するソリューションを設計し、LRU リンク リストをホット データ領域とコールド データ領域の 2 つの部分に分割して、事前読み取りの失敗とバッファー プールの汚染の問題を解決しました。

以上がMySQLのバッファプールの詳しい説明です。MySQLのバッファプールについてさらに詳しく知りたい方は、123WORDPRESS.COMの関連記事もぜひご覧ください!

以下もご興味があるかもしれません:
  • MySQL Innodbの主な機能挿入バッファ
  • MySQL クエリ キャッシュとバッファ プール
  • mysql 最適化のための重要なパラメータ key_buffer_size table_cache
  • mysql key_buffer_size設定を最適化する
  • mysql read_buffer_size の適切な設定は何ですか?
  • MySQL ソートが中止されました: ソート メモリが不足しています。サーバーのソート バッファ サイズを増やすことを検討してください。
  • MySQL ソースコードから Innodb バッファヒット率の計算を分析する
  • PHP での MySQL 操作バッファの使用法の詳細な説明
  • Mysql の最適化とチューニングにおける 2 つの重要なパラメータ: table_cache と key_buffer
  • mysql key_buffer_sizeパラメータの最適化設定
  • mysqldump によるバッファプール汚染の調査
  • MySQL 結合バッファの原理

<<:  XHTML 入門チュートリアル: XHTML とは何ですか?

>>:  VUE ユニアプリの基本コンポーネントの簡単な紹介

推薦する

EChartsマルチチャート連携機能の実装プロセス

表示するデータが多い場合、1 つのチャートに表示しても効果はよくありません。このとき、2 つのチャー...

Javascript 非同期プログラミング: Promise を本当に理解していますか?

目次序文基本的な使い方文法エラー処理プロミスチェーン呼び出し非同期と待機よく使われる方法1. Pro...

JavaScript ファクトリーパターンの説明

目次シンプルファクトリーファクトリーメソッド安全な工場方法アブストラクトファクトリー要約するシンプル...

FileZilla 425 FTP に接続できない (Alibaba クラウド サーバー) の解決策

Alibaba Cloud ServerがFTPに接続できないFileZilla 425 データ接続...

JS 矢印関数に適さないシナリオは何ですか?

目次概要オブジェクトにメソッドを定義するオブジェクトリテラルオブジェクトプロトタイプ動的コンテキスト...

MySQL 5.7.11 zip インストールと設定方法のグラフィックチュートリアル

1. MySQL 5.7.11 zipインストールパッケージをダウンロードするこのマシンはwin7 ...

xshell を使用して VMware で Linux に接続する方法 (2 つの方法)

【序文】最近、ITOO の試験システムのストレステストを行いたいので、自分のコンピュータに Lin...

Vue がコンポーネント通信を実装する 8 つの例

目次1. Props 親コンポーネント ---> 子コンポーネント通信2. $emit 子コン...

favico.ico---ウェブサイトicoアイコン設定手順

1. 正常に生成されたアイコン ファイルをダウンロードし、名前を favico.ico に変更して、...

Docker Swarm クラスタ管理の使用と原理の分析

Swarm クラスター管理導入Docker Swarm は Docker 用のクラスター管理ツールで...

WeChatミニプログラムページ間の価値転送を実装する方法の例

ミニプログラムページ間で値を渡すみなさんこんばんは。こんばんはと言うのは、これを夜に書いたからです。...

VMware で VMware ツールをインストールしてもインストール ファイルが表示されない問題を解決する方法

VMware ツールは VMware の使用に非常に便利です。そのため、VMware ツールをインス...

HTML で入力テキスト入力キャッシュのクリアを禁止する 2 つの方法

ほとんどのブラウザはデフォルトで入力値をキャッシュし、ctl+F5 を使用して強制的に更新することに...

CSS 疑似クラス: 空っぽだと光る (サンプルコード)

最近私の記事を読んだ人なら誰でも、私が現在WeChatミニプログラムプロジェクトを担当しており、その...

ESXI の仮想マシンにワークステーションをインストールするときに発生するネットワーク障害の解決策

問題の説明ESXI で Windows にワークステーションをインストールした後、内部の仮想マシンは...