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 ユニアプリの基本コンポーネントの簡単な紹介

推薦する

MySQLインデックスの基礎となるデータ構造の詳細

目次1. インデックスの種類1. B+ツリー2. MyISAM と InnoDB の B+ ツリー ...

ウェブサイトにファビコンを追加するためのヒント: URLの前の小さなアイコン

いわゆるファビコンは、Favorites Icon の略で、中国語ではウェブサイトアバターと呼ばれて...

レアタグフィールドセットと凡例の使用方法の詳細な説明

<fieldset>と<legend>については、ほとんどの人はおそらく馴染...

HTML要素のID属性とName属性の違い

今日、私は <a href="#13"></a> につい...

XHTML 入門チュートリアル: XHTML ハイパーリンク

ハイパーリンクはインターネット全体を接続していると言っても過言ではありません。ハイパーリンクは、別の...

CSS3を使用して背景画像の色を変更するさまざまな方法

CSS3 では画像の色を変更できます。これからは複数の絵をデザインする必要がなくなり、いつでも修正で...

HTML タグでの this の使用法の紹介

例えば:コードをコピーコードは次のとおりです。 <html> <ヘッド> &...

Dockerコンテナ間のホスト間通信 - オーバーレイベースの実装方法

オーバーレイネットワーク分析組み込みのホスト間ネットワーク通信は、常に Docker の待望の機能で...

Vueの使用に関する深い理解

目次Vueのコアコンセプトを理解するVueの双方向バインディングの原理と実装を探るVue 双方向バイ...

Jmeterはデータベースプロセスダイアグラムに接続します

1. MySQL jdbc ドライバー (mysql-connector-java-5.1.28.j...

ページ内のリストプルダウン効果を実現するための純粋なCSS

次のような効果がよく見られます。 そうです、ページ上でよく使われる「展開と折りたたみ」のインタラクシ...

React Hooksの詳細な説明

目次フックとは何ですか?クラスコンポーネント機能コンポーネントフックが作られた理由要約するフックとは...

Kubernetes を使用して Springboot または Nginx をデプロイするための詳細なチュートリアル

1 はじめに「Maven がワンクリックで Springboot を Docker リポジトリにデプ...

ボタンの権限判定を実装するためのVueカスタムv-has命令

アプリケーションシナリオバックグラウンド管理システムを例にとると、各ユーザーには異なるボタン権限があ...

Q&A: XML と HTML の違い

Q: xml と html の違いがわかりません。違いは何ですか? A: XMLと HTML の違い...