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

推薦する

Linux 7.7 でスワップ パーティション SWAP を設定する方法

Linux システムの Swap パーティション、つまり swap パーティションは、一般に仮想メモ...

Dockerコンテナ内でホストDocker操作を呼び出して実行する

まず、この投稿は Docker 初心者向けです。もちろん、ベテランであれば記事中の分割線以降の操作方...

MySQLクエリのパフォーマンスを分析する方法

目次スロークエリの基礎: データ取得の最適化データベースから不要なデータが要求されていないか確認する...

Vue CLI のモードと環境変数の詳細な説明

序文実際のプロジェクトの開発では、通常、プロジェクト開発フェーズ、テストフェーズ、最終オンラインフェ...

MySQL SHOW STATUSステートメントの使用

MySQL のパフォーマンス調整とサービス ステータスの監視を行うには、MySQL の現在の実行状態...

JS での矢印関数と this の記述と理解

目次序文1. JSで関数を書く方法1. 通常の関数の書き方2. 矢印関数の書き方2. 通常の関数でこ...

VueにおけるAxios非同期通信の詳細な説明

1. まず、インタラクティブに使用するための .json ファイルを作成します。json データ形式...

MySQL マスター/スレーブ ステータスを監視するシェル スクリプト

Linuxでシェルスクリプトを共有して、MySQLのマスタースレーブ状態を監視し、エンタープライズW...

nginxの基礎を学ぶ

目次1. nginx とは何ですか? 2. nginx で何ができるのか? 2.1 フォワードプロキ...

FileZilla を使用して FTP サーバーに接続するプロセスの図

最初にサーバー上に FTP サーバーをセットアップし始めたとき、接続できないことがわかったので、Fi...

MySQL 入門 - SQL 実行プロセス

目次1. プロセス2. コアアーキテクチャ2.1 サーバー層の基本コンポーネントの紹介3. ステート...

複数ページ通信を実現する JavaScript の sharedWorker の詳細な例

こんなことがありました。今日はGitHubで遊んでいました。最初はログインせずにいくつかのページを閲...

スライダーを作成するためのネイティブ js ドラッグ アンド ドロップ機能のサンプル コード

ドラッグ アンド ドロップはフロントエンドでよく使われる機能であり、多くのエフェクトで js のドラ...

MySQL の一般的なツール例の概要 (推奨)

序文この記事では主にMySQLでよく使われるツールに関する関連コンテンツを紹介し、皆さんの参考と学習...

IDEA を使用して Tomcat を設定し、JSP ファイルを作成する方法

idea を使用して JSP ファイルを書き込む前に、jdk 環境 (ここでは説明しません) と対応...