MySQL Innodbの主な機能挿入バッファ

MySQL Innodbの主な機能挿入バッファ

挿入バッファとは何ですか?

挿入バッファは、InnoDB ストレージ エンジンの重要な機能の 1 つです。挿入バッファはバッファ プールの一部であると理解されることがよくあります。この理解は一方的です。挿入バッファの情報の一部はメモリ内にあり、他の部分はデータ ページなどの物理ページに存在します。

InnoDB では、テーブルに自動増分主キーがある場合、このテーブルのデフォルトの挿入は非常に高速であることがわかっています。ここで主キーは自動増分であることに注意してください。自動増分でない場合、挿入はランダムになり、データ ページ分割のオーバーヘッドが発生する可能性があります。このように、挿入は順次行われず、遅くなります。別の状況として、挿入する ID が連続的ではなくランダムである場合、自動増分主キーがあっても、挿入速度は特に速くなりません。

主キーと非クラスター化インデックスを持つテーブルを次のように定義します。

テーブルtを作成する(

整数の自動増分、

b varchar(30)、

主キー(a)、

キー(b)

);

主キー a に従ってデータを挿入する場合、非クラスター化インデックス (セカンダリ インデックス b とも呼ばれる) の挿入は順次行われず、挿入パフォーマンスは必然的に低下します。

Innodb ストレージ エンジンは、このような状況に備えて挿入バッファーを設計しました。非クラスター化インデックスの挿入または更新操作では、毎回インデックス ページに挿入するのではなく、まず挿入された非クラスター化インデックス ページがバッファー プールにあるかどうかを判断します。ある場合は、直接挿入されます。ない場合は、まず挿入バッファーに入れて、この非クラスター化インデックスがリーフ ノードに挿入されたことをデータベースに通知します。実際には挿入されず、別の場所に格納されます。その後、挿入バッファーと補助インデックス リーフ ノードのマージ操作が、一定の頻度と状況で実行されます。この場合、複数のレコードの挿入を 1 つの操作にマージできることが多く、非クラスター化インデックスの個別挿入のパフォーマンスが大幅に向上します。

挿入バッファのトリガー条件は何ですか?

挿入バッファが使用されるには、2 つの条件を満たす必要があります。1 つ目は、インデックスがセカンダリ インデックスであること、2 つ目は、インデックスが一意ではないことです。上記の 2 つの条件が満たされると、挿入バッファを使用してデータベースの挿入操作のパフォーマンスを向上させることができます。

ここで注意すべき点は、プログラムが大量の操作を実行しているときに MySQL データベースがクラッシュした場合、実際の非クラスター化インデックスにマージされていない挿入バッファが多数存在し、回復に長い時間がかかる可能性があるということです。

なぜ一意のインデックスにできないのでしょうか?

一意のインデックスがサポートされていない理由は、補助インデックスが一意のインデックスである場合、挿入時に一意性を検証する必要があるためです。一意性を検証すると、個別の読み取りが発生し、オーバーヘッドが増加するため、挿入バッファはコストに見合いません。

次のように、show engine innodb status を通じて挿入バッファの使用状況を確認できます。

mysql--root@localhost:dms_alimetadata 20:35:24>>エンジンのinnodbステータスを表示\G
-------------------------------------
挿入バッファとアダプティブハッシュインデックス
-------------------------------------
Ibuf: サイズ 1、フリーリストの長さ 0、セグメントサイズ 2、マージ 0
統合された操作:
 挿入 0、削除マーク 0、削除 0
破棄された操作:
 挿入 0、削除マーク 0、削除 0

サイズはマージされたレコードページの数を表し、フリーリストlenはフリーリストの長さを表し、セグメントサイズは現在の挿入バッファサイズが2*16KBであることを示しています。

チェンジバッファの概念の紹介

最新のMySQL5.7はすでに変更バッファをサポートしています。実際、これはinnodb 1.0.xで導入されました。この変更バッファは挿入バッファのアップグレードとして理解できます。つまり、挿入、削除、更新を含む一般的なDML言語をバッファリングでき、それぞれ挿入バッファ、削除バッファ、パージバッファに対応しています。

もちろん、変更バッファによって使用されるオブジェクトは、依然として一意ではない補助インデックスです。

ここでは更新操作を例に挙げます。更新プロセスは 2 つの部分に分けられます。

最初の部分は、レコードの delete_mask を削除済みとしてマークすることです。delete_mask についてご存じない場合は、4 月 9 日の記事をお読みください。 2 番目の部分は、実際にレコードを削除することです。

削除バッファは更新の最初のプロセスに対応し、パージバッファは 2 番目の部分に対応します。

Innodb では、パラメータ innodb_change_buffering を通じてさまざまなバッファ オプションを有効にすることができます。このパラメータのオプション値は、挿入、削除、パージ、変更、すべて、なしなどです。このうち、挿入、削除、およびパージは上で説明した状況であり、変更は挿入と削除をオンにすることを意味し、すべてをオンにすることを意味します。デフォルトのパラメータは次のとおりです。

mysql--root@localhost:dms_alimetadata 21:13:37>>'%buffering%' のような変数を表示します。
        +-------------------------+-------+
| 変数名 | 値 |
+-------------------------+-------+
| innodb_change_buffering | すべて |
+-------------------------+-------+
セット内の1行(0.01秒)

innodb_change_buffer_max_size を通じて、change_buffer が使用するメモリの最大量を制御することもできます。このパラメータのデフォルト値は 25 (1/4) です。例は次のとおりです。

mysql--root@localhost:dms_alimetadata 21:20:52>>'%innodb_change_buffer_max_size%' のような変数を表示します。
+---------------------------------+-------+
| 変数名 | 値 |
+---------------------------------+-------+
| innodb_change_buffer_max_size | 25 |
+---------------------------------+-------+
セット内の 1 行 (0.00 秒)

上記の show engine innodb status コマンドの出力には、merged operation と discarded operation が表示されています。ここで、insert は挿入バッファ操作の数、delete mark は削除バッファ操作の数、delete はパージバッファ操作の数を示します。discarded operation は、変更バッファがマージされたときにテーブルが削除され、マージが不要であることを示します。

挿入バッファを実装するにはどうすればいいですか?

挿入バッファのデータ構造は B+ ツリーです。クラスター化インデックスと同様に、挿入バッファ B+ ツリーはグローバルに 1 つだけ存在し、すべてのテーブルの挿入バッファリングを担当します。この B+ ツリーは、共有テーブル スペース、つまり ibdata1 ファイルに配置されます。したがって、ibd ファイルを介してテーブル データを復元しようとすると、テーブルの補助インデックスのデータが挿入バッファにまだ残っている可能性があるため、チェック テーブルが失敗する可能性があります。したがって、ibd ファイルを介してファイルを復元した後、テーブルの補助インデックスを再構築するために修復テーブル操作が必要です。

挿入バッファはツリーなので、リーフノードと非リーフノードが必要です。非リーフノードには、クエリの検索キー値が格納されます。その構造は次のとおりです。

+---------+------------+--------+
| スペース | マーカー | 値 |
+---------+------------+--------+

この構造は合計 9 バイトを占め、スペースは挿入するレコードが配置されているテーブルのテーブル スペース ID を表します。この ID は各テーブルが持つ必要がある一意の ID です。スペースは 4 バイトを占め、マーカーは古いバージョンの挿入バッファーとの互換性を保つために 1 バイトを占め、オフセットはページのオフセットを示すために 4 バイトを占めます。

補助インデックスの挿入処理?

補助インデックスをデータ ページに挿入する場合、データ ページがバッファー プールになければ、InnoDB はルールに従って検索キーを構築し、挿入バッファーの B+ ツリーにレコードを挿入します。挿入プロセス中に、レコードを何らかの方法で構築する必要があります。挿入の最終結果は、次のようなレコードになります。

+---------+------------+-----------+---------+-------+-------+------+------+
| スペース | マーカー | 値 | メタデータ | | | | |
+---------+------------+-----------+---------+-------+-------+------+------+

最後に追加のメタデータ フィールドと他の 4 つのフィールドがあることがわかります。まずはメタデータ フィールドについて説明します。メタデータ フィールドは 4 バイトを占め、各レコードが挿入バッファーに入る順序を並べ替えるために使用されます。5 列目から、実際に挿入されたレコードの各フィールドの値になります。したがって、単純なデータ レコードと比較すると、挿入バッファーには 13 バイトのオーバーヘッドが追加で必要になります。

各マージ挿入バッファが確実に成功するためには、各補助インデックス ページの使用可能領域をマークするための特別なデータ ページを設定する必要があります。このデータ ページのタイプは挿入バッファ ビットマップであり、多数の補助インデックス ページの使用可能領域を追跡できます。ここで簡単に見てみましょう。その使い方は後ほど説明します。

挿入バッファをいつマージしますか?

レコードを挿入するための補助インデックス ページがバッファー プールにない場合は、補助インデックス レコードをこの B+ ツリーに挿入する必要があり、その後、挿入バッファーから実際の補助インデックスにマージされることはすでにわかっています。では、マージはいつ実行されるのでしょうか。

1. 補助インデックスページがバッファプールに読み込まれるとき

2. 挿入バッファ ビットマップが補助インデックス ページに十分な空き領域がないことをトラッキングする場合、一般的なしきい値は補助インデックス ページ領域の 1/32 です。

3. マスタースレッドは1秒に1回、マージ挿入バッファ操作を実行します。

上記は、MySQL Innodb の主要機能である挿入バッファの詳細です。Innodb の挿入バッファ機能の詳細については、123WORDPRESS.COM の他の関連記事にも注目してください。

以下もご興味があるかもしれません:
  • MySQL InnoDB ストレージエンジンのメモリ管理の詳細な説明
  • MySQL InnoDB ReplicaSet の簡単な紹介
  • MySQL InnoDB トランザクション ロック ソースコード分析
  • MySQL Innodb インデックス メカニズムの詳細な紹介
  • MySQLのInnoDBストレージエンジンにおけるさまざまなロックの詳細な説明
  • MySQL ストレージ エンジン InnoDB と MyISAM
  • MySQL の innoDB でファントム リードを解決する方法

<<:  JS でパブリッシュ サブスクライブ モデルを作成する

>>:  Web ページのデザインを学ぶときに習得すべきコードは何ですか?

推薦する

MySQLのlike演算子の詳細

1. はじめに不明な値または部分的に既知の値をフィルタリングする場合は、like 演算子を使用でき...

HTML およびプラグイン アプリケーションにおけるデータ カスタム属性の使用の概要

HTML にはデータ属性が含まれていることがよくあります。これらは HTML5 のカスタム属性です。...

Vueのリストレンダリングの詳細な説明

目次1. v-for: 配列の内容を走査する(よく使われる) 2. v-for: オブジェクトのプロ...

知っておくべき 7 つのネイティブ JS エラーの種類

目次概要1. 範囲エラー2. 参照エラー3. 構文エラー4. タイプエラー5. URIエラー6. 評...

親要素を基準にCSSの位置を絶対的に設定する方法についての簡単な説明

ご存知のとおり、CSS の絶対位置はデフォルトでドキュメントに応じて設定されます。たとえば、posi...

MySQL 接続クエリを本当に学びましたか?

1. 内部結合クエリの概要内部結合は、アプリケーションで非常に一般的な結合操作であり、通常はデフォ...

Vue ショッピングカートのケーススタディ

目次1. ショッピングカートの例2. コードの実装3. まとめ1. ショッピングカートの例一連の学習...

docker を使って sonarqube を構築する方法

目次1. Dockerをインストールする2. ソナーイメージをインストールする3. ソナーを使ってコ...

Flex モバイルレイアウトにおけるシングルラインレイアウトとダブルラインレイアウトの違いと使い方

レイアウトにul>liを使用した単一行レイアウトを以下に示します。 <ul class=...

ボタンに醜い灰色の枠線が付いています。これを削除するにはどうすればよいですか?

ダイアログをクロージャで使用し、右上隅の向こう側に閉じるボタンがあるダイアログを描画しました。ボタン...

LinuxベースのSelenium環境を構成し、操作を実装する

1. Linux で Selenium を使用する1. Chromeをインストールする次のコマンドを...

Navicat Premier の MySQL へのリモート接続エラー 10038 の解決方法

MySQL へのリモート接続が失敗する場合は、次の理由が考えられます。 1. 若い男性/女性の方は、...

MySQL Group by最適化の詳細な説明

目次標準的な実行プロセス最適化並べ替えを削除並べ替え成し遂げる要約する標準の Group by ステ...

Windows Server 2016 に Oracle をインストールする方法

1. Oracle をインストールします。インターネット上には Oracle のインストール手順が多...

PhpStormがVirtualBoxに接続できない問題を解決する

問題の説明: phpstorm の SFTP ホストを 192.168.122.1 に設定すると、接...