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 ページのデザインを学ぶときに習得すべきコードは何ですか?

推薦する

CSS のオーバーフロー:hidden エラーの解決方法

失敗の原因今日、カルーセルを書いていたときに、overflow;hidden; が失敗する可能性があ...

MyISAMとInnoDBの違いについてお話しましょう

主な違いは次のとおりです。 1. MySQL はデフォルトで MyISAM を使用します。 2. M...

高品質なコードを書く Web フロントエンド開発実践書の抜粋

(P4) Web 標準は一連の標準で構成されています。中心となる概念は、Web ページの構造、スタイ...

iFrameは背景を覆うポップアップレイヤーとして使うのに最適です

最近、私は「ぶどうコレクション」というプロジェクトに取り組んでいます。簡単に言うと、Budou ペー...

CSS ハック \9 と \0 は IE11\IE9\IE8 のハッキングには機能しない可能性があります

Web ページやフォームを設計するたびに、さまざまなブラウザ、特に IE ファミリの互換性の問題に悩...

MySQL の結合テーブルにインデックスを作成する方法

この記事では、MySQL で 2 つのテーブルを関連付ける結合テーブルにインデックスを作成する方法を...

Linux で履歴レコードを表示し、タイムスタンプを追加するためのヒント

Linux で履歴レコードを表示し、タイムスタンプを追加するためのヒントbashに詳しい人なら、hi...

vue+django でファイルをダウンロードする例

目次1. 概要2. Django プロジェクト3. Vueプロジェクト1. 概要プロジェクトで、ダウ...

Tomcat の構成と最適化ソリューションの詳細な説明

サービス.xml Server.xml 構成ファイルは、コンテナー全体を構成するために使用されます。...

MySQL マスタースレーブレプリケーションと読み取り書き込み分離の詳細な説明

記事マインドマップマスター/スレーブ レプリケーションと読み取り/書き込み分離を使用する理由は何です...

スクロールバーを非表示にする HTML の簡単な実装

1. 属性付きHTMLタグXML/HTML コードコンテンツをクリップボードにコピー< htm...

フォームデータを取得するための Node.js メソッドの 3 つの例

序文Nodejs はサーバーサイド言語です。開発中、登録やログインなどでは、判断のためにフォームを通...

MySQLのインストール時に発生する可能性のある問題

質問1:インストール中に net start mysql と入力すると、次のエラー メッセージが表示...

Linux Centos でスクリプトを使用して Docker をインストールする方法

Dockerの主な機能は何ですか?現在、Docker には少なくとも次のアプリケーション シナリオが...

Linux での MySQL 5.6.33 のインストールと設定のチュートリアル

このチュートリアルでは、LinuxでのMySQL 5.6.33のインストールと設定方法を参考までに紹...