ホームページ >データベース >mysql チュートリアル >MySQL の InnoDB ストレージ エンジンの詳細な紹介 (コード例)

MySQL の InnoDB ストレージ エンジンの詳細な紹介 (コード例)

不言
不言転載
2019-02-21 11:33:102491ブラウズ

この記事では、MySQL の InnoDB ストレージ エンジンについて詳しく説明します (コード例)。必要な方は参考にしてください。

InnoDB は MySQL のストレージ エンジン層に属し、プラグインの形式でデータベースに統合されます。 MySQL 5.5.8 以降、InnoDB がデフォルトのストレージ エンジンになります。 InnoDB ストレージ エンジンはトランザクションをサポートしており、その設計目標は主に OLTP アプリケーション向けです。その主な機能には、トランザクションのサポート、高同時実行性をサポートする行ロック設計、外部キーのサポート、自動クラッシュ回復、クラスター化インデックス構成テーブル構造などが含まれます。 (関連する推奨事項: MySQL チュートリアル )

システム アーキテクチャ

InnoDB ストレージ エンジンは、メモリ プール、バックグラウンド スレッド、およびメモリ プールの 3 つの部分で構成されます。ディスクストレージ。

MySQL の InnoDB ストレージ エンジンの詳細な紹介 (コード例)

#スレッド

InnoDB はマルチスレッド モデルを使用し、バックグラウンドで複数の異なるスレッドがさまざまなタスクの処理を担当します

マスター スレッド

マスター スレッドはコア バックグラウンド スレッドであり、主にバッファ プール内のデータをディスクに非同期に更新してデータの一貫性を確保します。ダーティ ページの更新、マージされた挿入バッファ、UNDO ページのリサイクルなどが含まれます。

IO スレッド

InnoDB ストレージ エンジンでは、書き込み IO リクエストを処理するために非同期 IO (Async IO) が広く使用されており、IO スレッドのジョブは主にこれらの IO リクエストのコールバックを担当します。 。

スレッドのパージ

トランザクションがコミットされた後、トランザクションで使用されていた UNDO ログは不要になる可能性があるため、割り当てられ使用された UNDO ページをリサイクルするには、スレッドのパージが必要です。 InnoDB は複数のパージ スレッドをサポートしており、UNDO ページのリサイクルを高速化し、CPU 使用率を高め、ストレージ エンジンのパフォーマンスを向上させることができます。

ページ クリーナー スレッド

ページ クリーナー スレッドは、マスター スレッドのダーティ ページ更新操作を置き換えるために使用され、元のマスター スレッドの作業とユーザー クエリ スレッドのブロックを軽減することです。 、InnoDB ストレージ エンジンのパフォーマンスがさらに向上します。

メモリ

InnoDB ストレージ エンジンのメモリ構造

MySQL の InnoDB ストレージ エンジンの詳細な紹介 (コード例)

バッファ プール

InnoDB ストレージエンジンはディスク ストレージに基づいており、ページ内のレコードを管理します。ただし、CPU 速度とディスク速度の間には隔たりがあるため、ディスクベースのデータベース システムでは、データベース全体のパフォーマンスを向上させるためにバッファー プール レコードを使用することがよくあります。

バッファ プールは、実際にはメモリの速度を使用して、データベースのパフォーマンスに対する遅いディスク速度の影響を補います。データベースが読み取り操作を実行すると、ディスク内のページがまずバッファ プールに置かれ、次に同じページが読み取られるときに、最初にページ データがバッファ プールから取得され、キャッシュとして機能します。

データ変更操作では、バッファ プール内のページ データが最初に変更され、次にチェックポイントと呼ばれるメカニズムを使用してディスクにフラッシュされます。

バッファ プールのサイズは、データベースの全体的なパフォーマンスに直接影響します。InnoDB ストレージ エンジンの場合、バッファ プールの構成はパラメータ innodb_buffer_pool_size によって設定されます。

SHOW VARIABLES LIKE 'innodb_buffer_pool_size' コマンドを使用して、バッファ プール構成を表示します。

mysql> SHOW VARIABLES LIKE 'innodb_buffer_pool_size' \G
*************************** 1. row ***************************
Variable_name: innodb_buffer_pool_size
        Value: 134217728
1 row in set (0.01 sec)
バッファ プールにキャッシュされるデータ ページのタイプは、インデックス ページ、アンドゥ ページ、挿入バッファ、アダプティブ ハッシュ インデックス、InnoDB ロック情報、データ ディクショナリ情報など。インデックス ページとデータ ページはバッファ プールの大部分を占めます。

REDO ログ バッファリング

バッファ プール内のページ データがディスクよりも新しい場合、新しいデータをディスクにフラッシュする必要があります。 InnoDB は、ログ先行書き込み戦略を使用してデータを更新します。つまり、トランザクションが送信されると、まず REDO ログ バッファが一定の頻度でリセット ログ ファイルに書き込まれ、次にダーティ ページが書き込まれます。チェックポイント メカニズムに従ってディスクにフラッシュされます。

REDO ログ バッファーを非常に大きく設定する必要はありません。通常、8M でほとんどのアプリケーション シナリオに対応できます。 REDO ログは、リフレッシュをトリガーする次の 3 つの状況をサポートします。

    #マスター スレッドは、REDO ログ バッファを毎秒 REDO ログ ファイルにフラッシュします
  • # #各トランザクションがコミットされると、REDO ログ バッファは REDO ログ ファイルにフラッシュされます。
  • REDO ログ バッファ プールの残りの領域が 1/2 未満になると、REDO ログ バッファはREDO ログ ファイルにフラッシュされます。ログ ファイルの作成
##追加メモリ プール

MySQL の InnoDB ストレージ エンジンの詳細な紹介 (コード例)InnoDB ストレージ エンジンでは、メモリ管理が行われます。ヒープ方式で実行されるメモリと呼ばれる処理。一部のデータ構造自体のメモリを割り当てる場合、追加のメモリプールから適用する必要がありますが、この領域のメモリが不足する場合はバッファプールから適用されます。

#ロック

InnoDB でサポートされているロックは次のとおりです:

##共有ロックと排他ロック

    ##インテンション ロック
  • レコード ロック
  • ギャップ ロック

  • 自動インクリメント ロック

##共有ロックと排他的ロック

InnoDBこのエンジンは、共有 (S) ロックと排他的 (X) ロックという 2 つの標準の行レベル ロックを実装します。共有ロックを使用すると、ロックを保持しているトランザクションはデータ行を読み取ることができ、排他ロックを使用するとトランザクションはレコード行に書き込むことができます。

トランザクションが共有ロックを保持している場合、他のトランザクションは引き続きこの行レコードの共有ロックを取得できますが、この行レコードの排他ロックを取得することはできません。トランザクションが行の排他ロックを取得すると、他のトランザクションはこの行の共有ロックと排他ロックを取得できなくなります。

インテンション ロック

InnoDB では、インテンション ロックはテーブル レベルのロックであり、共有ロックと排他ロックに分けられます。

  • インテンション共有lock : 特定の行の共有ロックを取得しようとしています

  • 意図的排他ロック: 特定の行の排他ロックを取得しようとしています

トランザクションは共有ロックまたは排他ロックを取得しています。まず、意図共有ロックまたは排他ロックを取得する必要があります。意図ロックは、テーブル上の他の操作をブロックしません。他のトランザクションに共有ロックまたは排他ロックを取得することを通知するだけです。とある列。

レコード ロック

レコードは、インデックスに作用する一種のロックです。現在のテーブルにインデックスがない場合、レコード自体ではなく、特定のレコードのインデックスをロックします。 InnoDB は非表示のクラスター化インデックスを作成し、レコード ロックは非表示のクラスター化インデックスをロックします。

ギャップ ロック

ギャップ ロックとレコード ロックはインデックスにも作用します。違いは、レコード ロックは 1 つのインデックス レコードにのみ作用し、ギャップ ロックは範囲内のインデックスをロックできることです。 InnoDB のギャップ ロックの唯一の機能は、他のトランザクションによる操作の挿入を防ぎ、それによってファントム読み取りの発生を防ぐことです。

自動インクリメント ロック

自動インクリメント ロックは特別なテーブル レベルのロックで、自動インクリメント列を含む挿入操作にのみ適用されます。トランザクションがデータを挿入しているとき、他のトランザクションはトランザクション全体が挿入操作を完了するのを待ってから、挿入操作を実行するためのロックを取得する必要があります。

トランザクション

ACID

トランザクションについて話すとき、トランザクションは OLTP としてのデータベースの最も重要な機能です。 ACID の特徴:

  • 原子性: トランザクションの最小作業単位 (すべて成功するかすべて失敗するか)

  • 一貫性: 開始とトランザクションの終了 その後、データベースの整合性は破壊されません。

  • 分離 (分離): 異なるトランザクションは相互に影響しません。4 つの分離レベルは RU (コミットされていない読み取り) です。 、RC (コミットされた読み取り)、RR (繰り返し読み取り)、SERIALIZABLE (シリアル化)

  • Durability (耐久性): トランザクションが送信された後、データへの変更は、たとえトランザクションが送信されても​​永続的です。システム障害が失われることはありません

InnoDB のアトミック性、永続性、一貫性は、主に Redo Log、Undo Log、および Force Log at Commit メカニズムを通じて実現されます。 REDO ログはクラッシュ時にデータを回復するために使用され、Undo ログはトランザクションの影響を元に戻すために使用され、マルチバージョン管理にも使用できます。コミット時にログを強制するメカニズムにより、トランザクションがコミットされた後も REDO ログが確実に保持されます。分離はロックと MVCC によって保証されます。

分離レベル

MySQLには、トランザクションに次の4つの分離レベルがあります:

  • Read Uncommitted Read

  • Read Committed Read Committed

  • Repeatable ReadRepeatable Read

  • Serializable Serializable

4 つの分離レベルを理解する前に、他の 3 つの用語を理解する必要があります:

  • ダーティ リーディング

トランザクション a は、コミットされていないデータを読み取ります。トランザクション b が何らかの理由でロールバック操作を実行すると、トランザクション a によって読み取られたデータが使用できなくなり、何らかの異常な結果が発生します。

  • Non-repeatable read

トランザクション サイクル中に特定のデータが複数回クエリされ、同時にこれらのデータが更新されますまたは、b トランザクション削除操作で更新されます。その場合、トランザクション a の各クエリの結果は異なる可能性があります。

  • ファントム リーディング

ファントム リーディングの結果は、実際には非反復読み取りと同じです。違いは、非反復読み取りであることです。主に他の目的で、トランザクションは編集 (更新) および削除 (削除) 操作を実行しました。ファントム読み取りは主に挿入操作に使用されます。つまり、トランザクションのライフサイクル中に、別のトランザクションから新しく挿入されたデータがクエリされます。

Read uncommitted read

Uncommitted read. この場合、あるトランザクション a は別のトランザクション b のコミットされていないデータを参照できます。この時点でトランザクション b がロールバックされた場合、トランザクション a はどのようなものを取得しますか。はダーティ データであり、ダーティ リードの意味です。

この分離レベルは、通常、MySQL InnoDB での使用には推奨されません。

Read Committed Read Committed

Read Committed、最初からコミットされるまでトランザクションによって行われた変更は、他のトランザクションには表示されません。ダーティ リードの問題は解決されましたが、ファントム リード現象は存在します。

Repeatable ReadRepeatable Read

Repeatable Read、このレベルは、同じトランザクション内で同じレコードを複数回読み取った結果の一貫性を保証し、InnoDB ストレージ エンジンでのファントム読み取りと非繰り返し読み取りの両方を解決します。質問を読んでください。

InnoDB エンジンは、Next-Key Lock を使用してファントム読み取りの問題を解決します。 Next-Key Lock は、行ロックとギャップ ロックの組み合わせです。InnoDB がインデックス レコードをスキャンするとき、最初に行ロック (レコード ロック) をインデックス レコードに追加し、次にギャップを追加します。インデックス レコードの両側のギャップ。ギャップ ロックを追加すると、他のトランザクションはこのギャップ内のレコードを変更したり挿入したりできなくなります。

Serializable Serializable

Serializable はトランザクションを強制的にシリアルに実行することでファントム読み取りの問題を回避します。ただし、Serializable はデータの読み取り行ごとに実行されます。ロックされているため、多くのタイムアウトやロック競合の問題が発生する可能性があり、同時実行性が急激に低下するため、MySQL InnoDB での使用はお勧めできません。

#オープン トランザクション

  • BEGIN、BEGIN WORK、START TRANSACTION

  • ## BEGIN コマンドを実行しても、実際には新しいトランザクションは開始されません。エンジン層 トランザクションは現在のスレッドにマークを設定するだけで、明示的に開かれたトランザクションを表します。

    START TRANSACTION READ ONLY
  • MySQL サーバーがデータを変更する SQL を受信すると、そのトランザクションを直接拒否します。変更するとエラーが返されます。このエラーに対してはエンジン層には入りません。

    START TRANSACTION READ WRITE
  • 現在のスレッドの読み取り専用ステータスが次の場合に、スーパー ユーザーが読み取り/書き込みトランザクションを開始できるようにします。真実。

    一貫したスナップショットでトランザクションを開始
  • ## トランザクションを開くと、エンジン層に入り、
  • readview
が開きます。この操作は RR 分離レベルでのみ有効です。それ以外の場合はエラーが報告されます。

Undo ログ

データが変更されると、対応する Undo ログが記録され、トランザクションが失敗するかロールバックした場合、記録された Undo ログを使用してロールバックできます。アンドゥログは、変更前のデータイメージを記録する論理ログです。変更中に現在のデータを同時に読み取る必要がある場合、バージョン情報に基づいてこの行に記録されている以前のバージョンのデータを分析できます。さらに、Undo ログには永続性保護も必要であるため、Undo ログは REDO ログも生成します。

トランザクションの送信

グローバル トランザクション ID ジェネレーターを使用してトランザクション NO を生成し、現在の接続のトランザクション ポインター (
    trx_t
  1. ) をグローバル トランザクション ID ジェネレーターに追加します。リンク リスト (

    trx_serial_list) のコミット トランザクション

    は、Undo をマークします。このトランザクションが UndoPage を 1 つだけ使用し、使用量が 3/4 ページ未満の場合は、これをマークします。ページは
  2. TRX_UNDO_CACHED
  3. です。条件が満たされず

    insert undo の場合、TRX_UNDO_TO_FREE としてマークされます。それ以外の場合、取り消しは更新取り消しであり、マークされます。 TRX_UNDO_TO_PURGE として。 TRX_UNDO_CACHED とマークされた取り消しは、エンジンによってリサイクルされます。

  4. update undo
  5. undo セグメント 履歴リスト に入れ、rseg_history_len## をインクリメントします # (グローバル)。同時に、ページの TRX_UNDO_TRX_NO を更新します。データが削除された場合は、delete_mark をリセットし、

    undate undo を変更します。
  6. から
  7. update_undo_list

    から削除します。 TRX_UNDO_CACHED としてマークされている場合は、update_undo_cached キュー ## に追加します。 ##mtr_commit (元に戻す/やり直しのログはパブリック バッファに書き込まれます) この時点で、ファイル レベルのトランザクションがコミットされます。この時点でクラッシュした場合でも、再起動後にトランザクションが送信されることが保証されます。次に行うことは、メモリ データ ステータスを更新することです (

    trx_commit_in_memory
  8. )
  9. 読み取り専用トランザクションでは、readview を変更するだけで済みます。 global

    から readview
  10. リンク リストから削除し、
  11. trx_t

    構造内の情報をリセットします。読み取り/書き込みトランザクションは、まずトランザクション ステータスを TRX_STATE_COMMITTED_IN_MEMORY に設定し、すべての行ロックを解放し、rw_trx_listreadview から trx_t を削除する必要があります。グローバル readview リンク リストから削除されました。 insert undo がある場合は、ここで削除します。 update undo がある場合は、パージ スレッドを起動して、ゴミをクリーンアップします。 最後に、trx_t# の情報をリセットします。 ## 簡単にダウンロードできるように、トランザクションは を使用してロールバックします。

    読み取り専用トランザクションの場合は、直接返されます

トランザクション全体をロールバックするか、トランザクションの一部をロールバックするかを決定します。トランザクションの一部である場合は、保持する必要がある Undo ログの数を記録し、余分なログをすべてロールバックします。
  • ##From

    update undo
  • insert undo

    の間の最後の取り消しを検索し、この取り消しからロールバックを開始します

  • #update undo の場合、削除対象としてマークされたレコードはクリーニング対象としてマークされ、更新されたデータは最も古いバージョンにロールバックされます。 insert undo の場合は、クラスター化インデックスとセカンダリ インデックスを直接削除します

  • すべての元に戻す操作がロールバックされたか、指定された元に戻す操作にロールバックされた場合は、元に戻すログを停止して削除します

インデックス

InnoDB エンジンは、インデックス構造として B ツリーを使用します。主キー インデックスのリーフ ノード データ フィールドには完全なフィールド データが格納され、非主キー インデックスのリーフ ノードには、そのフィールドを指す値データが格納されます。主キー。

MySQL の InnoDB ストレージ エンジンの詳細な紹介 (コード例)

上の図は、InnoDB メイン インデックス (データ ファイルでもあります) の概略図であり、リーフ ノードに完全なデータ レコードが含まれていることがわかります。このインデックスはと呼ばれます。クラスター化インデックス。 InnoDB のデータ ファイル自体は主キーによって集約されるため、InnoDB ではテーブルに主キーが必要です。明示的に指定されていない場合、MySQL システムはデータ レコードを一意に識別できるカラムを主キーとして自動的に選択します。列が存在しない場合、MySQL は InnoDB テーブルの主キーとして暗黙的なフィールドを自動的に生成します。このフィールドの長さは 6 バイトで、型は long です。

InnoDB の補助インデックス データ フィールドには、アドレスの代わりに、対応するレコードの主キーの値が格納されます。つまり、InnoDB のすべてのセカンダリ インデックスは、データ フィールドとして主キーを参照します。クラスター化インデックスの実装により、主キーによる検索が非常に効率的になりますが、補助インデックス検索ではインデックスを 2 回取得する必要があります。まず、補助インデックスを取得して主キーを取得し、次に主キーを使用して主キー内のレコードを取得します。索引。

以上がMySQL の InnoDB ストレージ エンジンの詳細な紹介 (コード例)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はsegmentfault.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。