MySQLInnodbテクニカルインサイダーの読書ノート

1.Innodbのアーキテクチャ

バックグラウンドスレッドは次のように分けられます。 

1>マスタースレッド

主に、バッファプール内のデータをディスクに非同期でフラッシュし、ダーティページのフラッシュ、挿入バッファのマージ(Insert Buffer)、元に戻すページのリサイクルなど、データの整合性を確保します。

2> IOスレッド

主に、Aioを使用した書き込み要求のコールバック処理を担当します。それらは、書き込み(4)、読み取り(4)、挿入バッファー、logioスレッドなどに分けられます。

3>パージスレッド

トランザクションがコミットされた後、使用されたUNDOログは不要になる可能性があるため、使用および割り当てられたUNDOページを再利用するにはPurgeThreadが必要です。

4>ページクリアナースレッド 

主にダーティページの更新を担当します。

羊: 

1>バッファ

Innodbはディスクストレージに基づいていますが、CPUとディスクの速度の間に大きなギャップがあるため、メモリの速度がギャップを埋めるために使用されます。データベースでのデータページの読み取りでは、最初にページがバッファに読み込まれます。次に同じページが読み込まれると、バッファにあるかどうかが判断されます。ある場合はページが直接読み込まれ、そうでない場合はから読み込まれます。ディスク。ページ上。

データベース内のページを変更する場合、最初にバッファ内のページが変更され、次に特定の頻度でディスクにフラッシュされます。バッファからディスクへのページフラッシュは、ページが変更されるたびにトリガーされるわけではありませんが、チェックポイントメカニズムを介してディスクにフラッシュされます。バッファーにバッファーされるページのタイプは、インデックスページ、データページ、元に戻すページ、挿入バッファー、アダプティブハッシュインデックス、innodbに格納されているロック情報、データディクショナリ情報などです。

2> LRU、フリーリスト、フラッシュリスト

Innodbのバッファーは、LRUアルゴリズムによって管理され、最も頻繁に使用されるのはリストの先頭で、最も使用されないのはリストの最後です。バッファプールが新しく読み取られたページを格納できない場合、LRUの最後のページが最初に解放されます。Innodbのデフォルトのバッファープールサイズは、デフォルトで16KBです。

3> REDOログバッファ(REDOログバッファ)

Innodbは、最初にREDOログ情報をこのバッファーに保存し、次にそれを特定の頻度でREDOログファイルに更新します。次の3つの状況では、REDOログバッファ内のデータがREDOログファイルに
フラッシュされます。1)マスタースレッドは、REDOログバッファをREDOログファイルに毎秒フラッシュします。

2)各トランザクションがコミットされたとき。

3)REDOログバッファのスペースが1/2未満の場合。

チェックポイントテクノロジー:

現在のトランザクションデータベースシステムはWAL方式を採用しており、トランザクションがコミットされると、最初にREDOログが書き込まれ、次にページが変更されます。データベースがダウンしている場合、データはREDOログを介して復元できます。次のチェックポイントメソッドに分けられます。

1>シャープなチェックポイント

データベースが閉じられると発生し、すべてのダーティページ(変更されたページ)がディスクにフラッシュバックされます

2>ファジーチェックポイント

 1)マスタースレッドチェックポイント(マスタースレッドによって1秒ごとまたは10秒ごとにREDOログファイルに更新されます)

 2)FLUSH_LRU_LISTチェックポイント(エンジンは、LRUリストに約100の空きページがあることを確認する必要があるため)

 3)非同期/同期チェックポイント(REDOログファイルが利用できないため、この時点で一部のページを強制的にディスクにフラッシュバックする必要があります)

 4)ページが汚れているチェックポイントが多すぎる 

Innodbの主な機能:

1、バッファを挿入 

非クラスター化インデックスの挿入および更新操作の場合、毎回インデックスページに直接挿入するのではなく、最初に、挿入された非クラスター化インデックスページがバッファープールにあるかどうかを判断します。ある場合は直接挿入します。そうでない場合は、最初に挿入バッファでは、挿入バッファと補助インデックスリーフノードのマージ操作が特定の頻度と状況で実行されます。このとき、通常、複数の挿入を1つの操作にマージできるため、非挿入の挿入パフォーマンスが大幅に向上します。 -クラスター化インデックス。

挿入バッファーのデータ構造はB +ツリーであり、共有テーブルibdata1スペースに配置されます。

挿入バッファを使用するには、次の2つの条件を満たす必要があります
。1)インデックスが補助インデックスである

2)インデックスは一意ではありません

データベースがダウンしている場合、多数の挿入バッファーが非クラスター化インデックスにマージされず、リカバリーに長い時間がかかる場合があります。

2、バッファを変更します

innodbエンジンは、DML操作(それぞれ、挿入、削除、更新、挿入バッファー、削除バッファー、パージバッファー)をバッファーに入れることができます。変更バッファの該当するオブジェクトは、依然として一意ではないインデックスです。レコードの更新は、次の2つのプロセスに対応します
。1)レコードを削除済みとしてマークします(削除バッファーはこの段階に対応します)

2)レコードは実際に削除されます(パージバッファーはこの段階に対応します)

3、インサートバッファをマージ

発生する可能性があります:

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

2)挿入バッファビットマップページが、補助インデックスページに空き領域がないことをトレースした場合。

3)マスタースレッド

3.二重書き込み

二重書き込みは2つの部分で構成され、1つの部分はメモリへの二重書き込みでサイズは2MBで、もう1つの部分は物理ディスク上の128ページの共有テーブルスペース、つまり2つの領域で、サイズは同じ2MBです。バッファのダーティページを更新する場合、ダーティページはディスクに直接書き込まれませんが、ダーティページは最初にmemcpy関数を介してメモリ内のダブルライトバッファにコピーされ、次にダブルライトバッファを介して2回に分割されます。毎回1MBを順次共有表スペースの物理ディスクに書き込み、すぐにfsync関数を呼び出してディスクを同期し、キャッシュ書き込みによる問題を回避します。プロセスを見つけるプロセスでは、二重書き込みが連続的であるため、順次書き込みのプロセス全体が高価ではありません。二重書き込みページが書き込まれた後、二重書き込みバッファ内のページが各表スペースファイルに書き込まれます。この時点では、書き込みは個別です。

4.適応ハッシュインデックス

innnodbストレージエンジンは、テーブルの各インデックスエントリページのクエリを監視します。ハッシュインデックスの確立が速度の向上をもたらすことが観察された場合、ハッシュインデックスの確立は適応ハッシュインデックス(AHI)と呼ばれます。AHIでは、このページのアクセスモードが同じである必要があり、ハッシュインデックスはクエリとのみ等しくなり、範囲クエリは実行できません。

5.非同期IO(AIO)

非同期IOは、IOマージを実行して、複数のIOを1つのIOにマージできます。たとえば、隣接するページでの3つのIO操作の場合、それらを1つにマージできます。

6.ネイバーページを更新します。ページを更新すると
、innodbはそのページが配置されている領域のすべてのページを検出します。ダーティページの場合は、一緒に更新します。

7.開始、終了、復元

2.Innodbをロックします

1.一貫した非ロック読み取り

これは、innodbエンジンが、行マルチバージョンを介して現在の実行時間データベースのデータを読み取ることを意味します。読み取り行が削除および更新操作を実行している場合、読み取り操作は行ロックの解放を待機しませんが、読み取り行データのスナップショット。この実装は、元に戻すセグメントを介して実装されます。元に戻すは、トランザクション内のデータをロールバックするために使用されます。スナップショットデータの読み取りにはロックは必要ありません。トランザクション分離レベルの読み取りコミットおよび反復可能読み取りでは、innodbエンジンは非ロック読み取り一貫性読み取りを使用しますが、読み取りコミットでは、ロックされている最新のスナップショットデータを読み取り、反復可能読み取り読み取りでは、トランザクションの開始時に行データを読み取ります。バージョン。

2.整合性ロックの読み取り

Innodbは、selectステートメントに対して2つの一貫したロック読み取りをサポートします。

SELECT ***** FOR UPDATE(Xロックを読み取り行に追加します。他のトランザクションはロックを追加できませんが、読み取りは可能です)

SELECT ***** LOCAK IN SHARE MODE(Sロックを読み取り行に追加します。他のトランザクションでもSロックを追加できますが、Xロックを追加することはできません)

3.自己成長とロック

挿入の種類は次のとおりです。 

古いバージョンのinnnodbには、自動インクリメント値を持つ各テーブルの自動インクリメントカウンターがあります。自動インクリメントカウンターを含むテーブルに挿入すると、このカウンターが初期化されます。次のステートメントを実行して、カウンターの値を取得します。 :SELECT MAX(auto_inc_col)FROM t FOR UPDATE;挿入操作は、この自己増加カウンター値に基づいて自己増加列に1を追加します。実行効率を向上させるために、トランザクションの完了後にロックは解放されません。 、ただし、自己インクリメント値の挿入が完了した後、SQLステートメントの直後にリリースします。

新しいバージョンでは、軽量のミューテックス自己成長実装メカニズムが追加されています。innodbは、自己成長モードを制御するためのパラメーターinnodb_autoinc_lock_modeを提供します。可能な値は次のとおりです:

4.行ロックの3つのアルゴリズム

1)レコードロック:単一行レコードのロック。

2)ギャップロック:ギャップロック、範囲をロックしますが、レコード自体は含まれません。

3)Next-Key Lock:Gap-Lock + Record Lockは、範囲をロックし、レコード自体をロックします。左開きと右閉じです。クエリに一意のインデックスが含まれている場合、ロックはレコードロックにダウングレードされます。 。

4)前のキーロック:ギャップロック+レコードロック、範囲のロック、レコード自体のロック。これは、左を閉じて右を開く方法です。

5.ロックの問題

1)ダーティリード

トランザクションは、コミットされていない別のトランザクションのデータを読み取ります

2)繰り返し不可能な読み取り(ファントムの問題)

あるトランザクションは、別のトランザクションによって送信されたデータを読み取ります。innodbでは、繰り返し不可能な読み取りの問題を回避するために、Next-KeyLockアルゴリズムが使用されます。

3)失われた更新

あるトランザクションの操作が別のトランザクションの更新操作によって上書きされ、データの不整合が発生します。更新が欠落している必要性を回避するには、更新が欠落している場合のトランザクションの操作を、並列化ではなくシリアル化する必要があります。

6.デッドロック

デッドロックとは、実行プロセス中にロックリソースの競合が発生したために、2つ以上のトランザクションが相互に待機している状況を指します。デッドロックを解決する方法は次のとおりです
。1)残業待機

2)デッドロックの検出。グラフを待つ(グラフを待つ)ことにより、デッドロックの存在を検出します。

3.事務

1.トランザクションのACID特性

原子性、一貫性(トランザクションは、データベースの1つの状態を次の一貫性のある状態に変換します)、分離(コミットする前に、各読み取りおよび書き込みトランザクションが他のトランザクションから見えないようにする必要があります)、耐久性(トランザクションはコミットされると永続的です)

2.業務の分類

1)フラットトランザクション

すべての操作は同じレベルに属し、BEGIN WORKで始まり、COMMITWORKまたはROLLBACKWORKで終わります。その間の操作はすべてアトミックであり、すべてが実行されるか、すべてがロールバックされます。

2)セーブポイントのあるフラットトランザクション

トランザクションの実行中に、トランザクションの以前の状態へのロールバックを許可します。保存ポイントは、エラーが発生したときにトランザクションが現在の状態を保存できるように、トランザクションの状態を記憶する必要があることをシステムに通知するために使用されます。

3)チェーン取引

4)ネストされたトランザクション

5)分散トランザクション

3.事務の実現

原子性、一貫性、および耐久性は、データベースのREDOログ(トランザクションの原子性と耐久性を確保するため)およびUNDOログ(トランザクションの一貫性を確保するため)を通じて実現されます。

1>やり直し 

REDOログは、トランザクションの耐久性、つまりトランザクションのDを実現するために使用されます。これは2つの部分で構成されています。1つは揮発性のメモリ内のREDOログバッファで、もう1つは永続的なREDOログファイルです。

Innodbは、トランザクションストレージエンジンです。ForceLogatCommitメカニズムを使用して、トランザクションの永続性を実現します。つまり、トランザクションがコミットされると、トランザクションのすべてのログをREDOログファイルに書き込んで永続化する必要があります。COMMIT操作が完了します。完了したと見なされる前に。ここでのログはREDOログを指します。Innodbでは、REDOログとUNDOログの2つの部分で構成されています。REDOログはトランザクションの耐久性を確保するために使用され、UNDOログはロールバックおよびMVCC機能を支援するために使用されます。REDOログは基本的に順番に書き込まれ、データベースの実行中にREDOログを読み取る必要はなく、UNDOログはランダムに読み書きされる必要があります。

ログがREDOログファイルに確実に書き込まれるようにするには、各REDOログバッファーがログファイルに書き込まれた後、innodbストレージエンジンがfsync操作を呼び出す必要があります。REDOログファイルが開かれ、O_DIRECTオプションが使用されていないため、REDOログファイルは最初にファイルシステムキャッシュに書き込まれます。ログが確実にディスクに書き込まれるようにするには、fsync操作を実行する必要があります。fsyncの効率はディスクのパフォーマンスに依存するため、ディスクのパフォーマンスがトランザクション送信のパフォーマンス、つまりデータベースのパフォーマンスを決定します。

Innodbエンジンを使用すると、ユーザーは非永続的な状況を手動で設定して、データベースのパフォーマンスを向上させることができます。つまり、トランザクションがコミットされると、ログはREDOログファイルに書き込まれず、一定期間待機してからfsync操作を実行します。トランザクションのコミット後にfsync操作を強制的に実行することはないため、明らかにデータベースのパフォーマンスを向上させることができます。ただし、データベースがダウンすると、一部のログがディスクにフラッシュされないため、トランザクションの最後の期間の期間が失われます。

パラメータinnodb_flush_log_at_trx_commitは、REDOログをディスクにフラッシュする戦略を制御するために使用されます。このパラメーターのデフォルト値は1です。これは、トランザクションがコミットされたときにfysnc操作を実行する必要があることを意味します。0の場合、トランザクションがコミットされたときにREDOログ書き込み操作が実行されないことを意味します。この操作はマスタースレッドでのみ完了し、REDOログfsync操作はマスタースレッドで毎秒実行されます。2の場合、トランザクションがコミットされたときにREDOログがREDOログファイルに書き込まれることを意味します。つまり、fsync操作なしでファイルシステムのキャッシュに書き込まれます。オペレーティングシステムがダウンしている場合は、再起動します。データベースはファイルシステムを失います。トランザクションはREDOログファイルの一部にフラッシュされます。

LSNは、ログシーケンス番号の略語であり、ログシーケンス番号を表します。InnoDBストレージエンジンでは、LSNは8バイトを占有し、単調に増加します。LSNの意味は次のとおりです。

1)REDOログ書き込みの合計量。

2)チェックポイントの場所。

3)ページのバージョン。

2>ログを元に戻す

トランザクションをロールバックするときに元に戻すログが必要です。したがって、データベースが変更されると、innodbストレージエンジンはREDOを生成するだけでなく、一定量の元に戻すこともできます。このように、ユーザーがトランザクションの実行のために失敗した場合、またはROLLBACKステートメントの要求のためにロールバックした場合、元に戻す情報を使用して、変更前の状態にロールバックできます。

元に戻すは、元に戻すセクションと呼ばれるデータベースの特別なセクションに保存されます。元に戻すセグメントは、共有テーブルスペースに存在します。元に戻すは論理ログであるため、データベースを論理的に元の状態に復元するだけです。すべての変更は論理的にキャンセルされますが、データ構造とページ自体はロールバック後にかなり異なる場合があります。したがって、データベースがロールバックされると、実際には前の操作とは逆になります。挿入操作ごとに、innodbストレージエンジンは削除操作を完了します。削除ごとに、innodbは挿入操作を実行します。更新操作ごとに、逆更新操作が実行されます。

ロールバック操作に加えて、元に戻すの別の役割はMVCCです。つまり、innodbのストレージエンジンでのMVCCの実装は、元に戻すログを介して行われます。ユーザーがレコードの行を読み取るときに、レコードが他のトランザクションによって占有されている場合、現在のトランザクションは、元に戻すことで前の行のバージョン情報を読み取り、非ロック読み取りを実現できます。同時に、undoもREDOを生成します。つまり、UNDOログにも永続的な保護が必要なため、UNDOの生成にはREDOログの生成が伴います。

ストレージ管理:
トランザクションは元に戻すログセグメントに割り当てられ、元に戻すログに書き込まれます。このプロセスもREDOログに書き込む必要があります。トランザクションがコミットされると、InnoDBは次のことを行います
。1)元に戻すログを挿入する後のパージ操作のリスト。

2)元に戻すログが配置されているページを再利用できるかどうかを判断し、再利用できる場合は、次のトランザクションに割り当てます。

トランザクションがコミットされた後、元に戻すログと元に戻すログが配置されているページをすぐに削除することはできません。これは、前の行バージョンのレコードを取得するために元に戻すログを使用する必要がある他のトランザクションが存在する可能性があるためです。ストーリーが送信されると、元に戻すログがリンクリストに追加され、元に戻すログと元に戻すログが配置されているページをパージスレッドで削除できるかどうかを判断できます。

ログ形式を元に戻す:

InnoDBには、元に戻すログの形式が2つあります
。1)元に戻すログを挿入する

挿入操作は現在のトランザクション自体にのみ表示され、他のトランザクションは表示されないため、パージ操作を必要とせずに、トランザクションがコミットされた直後に元に戻すログを削除できます。

2)元に戻すログを更新する 

更新元に戻すログは、削除および更新操作によって生成された元に戻すログオブジェクトを記録します。元に戻すログにはMVCCメカニズムが必要な場合があるため、トランザクションがコミットされたときにログを削除することはできません。送信時にログリンクリストを元に戻し、パージスレッドが最終的な削除を実行するのを待ちます。

パージ操作:

削除および更新操作では、元のデータを直接削除することはできません。パージは、削除および更新操作を最終的に完了するために使用されます。これは、MVCCが原因で、トランザクションは送信できなくなったときにすぐに処理されます。現時点では、他のトランザクションがこの行を参照している可能性があります。このレコードを削除できるかどうかは、パージによって判断されます。この行のレコードが他のトランザクションによって参照されていない場合は、削除操作を実際に実行できます。

グループコミット:

これは、1回のfsync中に複数のトランザクションログがファイルに書き込まれることを意味します。プロセスは次のとおりです。

(1)メモリ内のトランザクション情報を変更し、ログをREDOログバッファに書き込みます

(2)fsyncを呼び出すと、すべてのログがREDOログバッファーからディスクに書き込まれます。

1)フラッシュフェーズでは、各トランザクションのバイナリログがメモリに書き込まれます。

2)同期フェーズ、メモリ内のバイナリログファイルをディスクにフラッシュします。キューに複数のトランザクションがある場合、1つのfsync操作のみがバイナリログの書き込みを完了します。これはBLGCです。

3)コミットフェーズでは、リーダーが順序に従ってストレージエンジンレイヤートランザクション送信を呼び出し、Innodbストレージエンジンがグループコミットをサポートするため、prepare_commit_mutexによるグループコミットの失敗の元の問題が修正されます。

内部XAトランザクション:
トランザクションがコミットされると、最初にbinlogが書き込まれ、次にREDOログが書き込まれ、これら2つのファイルの書き込みはアトミックです。そうでない場合、マスターとスレーブの間に不整合が生じる可能性があります。トランザクション送信のプロセスも次のとおりです。

トランザクションが送信されると、innodbエンジンは最初に準備操作を実行し、トランザクションのxidを書き込み、次にバイナリログを書き込みます。innodbエンジンが送信される前にMySQLデータベースがダウンしている場合、データベースは最初に再起動されます。準備したUXIDトランザクションが送信されているかどうかを確認します。送信されていない場合は、ストレージエンジンレイヤーで再度送信します。

 

おすすめ

転載: blog.csdn.net/qq_32323239/article/details/107885518