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

推薦する

src 属性と href 属性の違い

src と href には違いがあり、混同される可能性があります。 src は現在の要素を置き換える...

Windows 10 で Hyper-V サービスをシャットダウンするいくつかの方法

VMware Workstation を使用して Windows 10 で仮想マシンを開くと、VMw...

MySQL はどのようにしてデータベースの削除と暴走を効果的に防ぐことができますか?

目次セーフモード設定テスト1. where句なしで更新および削除する2. 非インデックスキーの削除3...

Nginx アップロードファイルのサイズを変更する簡単な方法

オリジナルリンク: https://vien.tech/article/138序文私は、マークダウン...

フロントエンドパフォーマンス最適化に関する補足記事

序文私は、Web サイトのフロントエンド パフォーマンス最適化のための JavaScript と C...

Linuxでmysqlの定期的なコールドバックアップを実装するためにmysqldump+expect+crontabを使用するアイデアの詳細な説明

目次1. 遭遇した問題2. アイデア3. コード1. 遭遇した問題私たちは皆、mysqldump を...

幅の比率に応じて高さを変えるCSSを実装するいくつかの方法

[解決策1: パディングの実装]原理:要素の padding の値がパーセンテージの場合、このパーセ...

NginxはLua+Redisを使用してIPを動的にブロックします

1. 背景日常的なウェブサイトのメンテナンスでは、このような要件に頻繁に遭遇します。特定のクローラー...

MySQLからElasticsearchにデータを同期する方法の詳細な説明

目次1. 同期の原理2. ログスタッシュ入力JDBC 3. go-mysql-elasticsear...

Tomcat を使用して Centos 環境に SpringBoot WAR パッケージをデプロイする

戦争パッケージを準備する1. 既存のSpringBootプロジェクトを準備し、pomに依存関係を追加...

mysql8.0.0 winx64.zip 解凍バージョンのインストールと設定のチュートリアル

この記事はmysql8.0.0 winx64.zip解凍版のインストールチュートリアルを記録していま...

MySQL でコミットされていないトランザクション情報を見つける方法

少し前に、「ORACLE でコミットされていないトランザクションの SQL ステートメントを見つける...

CSS3アニメーションとHTML5の新機能の詳しい説明

1. CSS3アニメーション☺CSS3 アニメーションは、JavaScript を介して要素のスタイ...

HTMLページにビデオを挿入する方法の概要

ページでビデオ タグを使用する場合は、Ogg Theora または VP8 (これに問題がない場合)...

CocosCreatorがスキル冷却効果を実装

CocosCreatorがスキルCD効果を実現多くのゲームにはスキルがあります。プレイヤーがスキルボ...