1. 基本概念トランザクションは、ACID プロパティを満たす一連の操作です。トランザクションは、Commit によってコミットされ、Rollback によってロールバックされます。中間状態と一貫性のある状態(データベーステーブルに実際に存在する状態でもある)が存在します。 酸原子性: トランザクションは分割できない最小単位と見なされ、トランザクションのすべての操作は正常にコミットされるか、すべて失敗してロールバックされます。ロールバックは、トランザクションによって実行された変更操作を記録する UNDO ログを使用して実行できます。ロールバックすると、これらの変更操作を元に戻すことができます。 UndoLog: トランザクションのアトミック性を保証するために、データを操作する前に、まずデータを Undo ログにバックアップしてからデータを変更します。エラーが発生した場合、またはユーザーが ROLLBACK ステートメントを実行した場合、システムは Undo ログ内のバックアップを使用して、トランザクションが開始される前の状態にデータを復元できます。 REDO ログとは異なり、ディスク上には個別の UNDO ログ ファイルはありません。UNDO ログは、UNDO セグメントと呼ばれるデータベース内の特別なセグメントに格納されます。UNDO セグメントは共有表領域にあります。 Innodbは、レコードの各行に3つの隠しフィールドを実装しています。6バイトのトランザクションID(DB_TRX_ID)7バイトのロールバックポインタ(DB_ROLL_PTR)隠しID 一貫性: データベースは、トランザクションの実行前と実行後に一貫した状態を維持します。一貫性のある状態では、すべてのトランザクションは同じデータに対して同じ読み取り結果を持ちます。 分離: 1 つのトランザクションによって行われた変更は、最終的にコミットされるまで他のトランザクションには表示されません。 耐久性: トランザクションがコミットされると、行われた変更はデータベースに永久に保存されます。システムがクラッシュしても、トランザクション実行の結果は失われません。システムクラッシュが発生した場合、redoLog を使用して回復し、永続性を実現できます。データに対する論理的な変更を記録する undoLog とは異なり、redoLog はデータ ページに対する物理的な変更の概要を記録します。 3.自動コミットMySQL はデフォルトで自動コミット モードを使用します。つまり、トランザクションを開始するために start transaction ステートメントを明示的に使用しない場合、各操作はトランザクションとして扱われ、自動的にコミットされます。 4. トランザクション分離レベルコミットされていない読み取り: トランザクション内の変更は、コミットされていない場合でも他のトランザクションに表示されます。 コミットされた読み取り: トランザクションは、コミットされたトランザクションによって行われた変更のみを読み取ることができます。つまり、トランザクションによって行われた変更は、コミットされるまで他のトランザクションには表示されません。 反復可能読み取り: 同じトランザクションで同じデータを複数回読み取った結果が同じになることを保証します。直列化可能: トランザクションが直列に実行されるように強制し、複数のトランザクションが互いに干渉せず、同時一貫性の問題が起こらないようにします。この分離レベルでは、ロック メカニズムを使用して同時に 1 つのトランザクションのみが実行されるようにするため、つまりトランザクションが直列に実行されるようにするためにロックを実装する必要があります。 5. 同時実行の一貫性の問題背景 同時実行環境では、トランザクションの分離を保証することが難しいため、多くの同時実行一貫性の問題が発生します。 メインシーン 変更の消失: 変更の消失とは、トランザクションの更新操作が別のトランザクションの更新操作に置き換えられることを意味します。たとえば、トランザクション T1 と T2 の両方がデータの一部を変更します。最初に T1 がデータを変更してコミットし、その後 T2 がデータを変更します。T2 の変更により、T1 の変更が上書きされます。 ダーティ データの読み取り: ダーティ データの読み取りとは、異なるトランザクションの下で、現在のトランザクションが他のトランザクションによってコミットされていないデータを読み取ることができることを意味します。たとえば、T1 はデータを変更しますが、コミットせず、その後 T2 がデータを読み取ります。 T1 がこの変更を元に戻すと、T2 によって読み取られたデータはダーティ データになります。 反復不可能な読み取り: 反復不可能な読み取りとは、トランザクション内で同じデータ セットを複数回読み取ることです。トランザクションが終了する前に、別のトランザクションも同じデータ セットにアクセスして変更を加えます。2 番目のトランザクションによる変更により、最初のトランザクションによって 2 回読み取られたデータに不整合が生じる可能性があります。たとえば、T2 がデータを読み取り、T1 がそのデータを変更します。 T2 がデータを再度読み取ると、この読み取り結果は最初の読み取り結果とは異なります。 ファントム リード: ファントム リードは、本質的には繰り返し不可能な読み取りです。T1 はデータの範囲を読み取り、T2 はこの範囲に新しいデータを挿入し、T1 はこの範囲のデータを再度読み取ります。この読み取りの結果は、最初の読み取りの結果とは異なります。 まとめ: 6. ロックブロックの粒度: 行レベル ロック: すべてのリソースではなく、変更が必要なデータまたは行の一部のみがブロックされます。ロック競合の可能性は小さく、システムの同時実行性は高くなります。 テーブル レベルのロック: テーブル全体がロックされます。ロックされたデータの量が多すぎるため、ロック競合の可能性が大幅に高まり、システムの同時実行パフォーマンスが急激に低下します。 注意: ロックはリソースを消費します。すべてのロック操作 (ロックの取得、ロックの解放、ロック ステータスの確認など) は、システムのオーバーヘッドを増加させます。したがって、ロックの粒度が小さいほど、システムのオーバーヘッドは大きくなります。ロックの粒度を選択するときは、ロックのオーバーヘッドと同時実行性の間でトレードオフを行う必要があります。 ブロッキングタイプ 読み取り書き込みロック ミューテックス ロックは、X ロックと略され、書き込みロックとも呼ばれます。 共有ロックは S ロックと略され、読み取りロックとも呼ばれます。 意図ロック 主にテーブルロックだが、実際にはロックではない 行レベル ロックとテーブル レベル ロックが存在する場合、トランザクション T がテーブル A に X ロックを追加する場合、まず他のトランザクションがテーブル A またはテーブル A 内の任意の行をロックしているかどうかを検出する必要があります。次に、テーブル A のすべての行をチェックする必要があり、非常に時間がかかります。 IS/IX ロックは、実際のロックではなく、テーブルをロックする要求のみを示すため、相互に互換性があります。 7.MySQLの暗黙的および明示的なロック暗黙的ロック: MySQL の InnoDB ストレージ エンジンは 2 段階のロック プロトコルを使用します。このプロトコルは、分離レベルに応じて必要なときに自動的にロックし、すべてのロックが同時に解除されます。これを暗黙的ロックと呼びます。 2 段階ロック プロトコル: ロックとロック解除は 2 段階に分かれています。シリアル化可能なスケジュールとは、同時実行制御により、同時に実行されたトランザクションの結果がシリアルに実行されたトランザクションの結果と同じになることを意味します。シリアルに実行されたトランザクションは互いに干渉せず、同時実行の一貫性の問題は発生しません。 または、特定のステートメントを使用して明示的なロックを実行します: SELECT ... LOCK In SHARE MODE; (共有ロック) SELECT ... FOR UPDATE; (排他ロック) トランザクションが完了してコミットされると、ロックは自動的に解除されます。 MySQL 3レベルブロッキングプロトコル レベル 1 ロック プロトコル: トランザクション T がデータ A を変更する場合、変更内容が失われる問題を解決するために、X ロックを追加し、トランザクション T が終了した後にのみロックを解除する必要があります。現時点では、2 つのトランザクションが同時に同じデータを変更することはできません。そうしないと、トランザクションの変更が上書きされません。 レベル 2 ロック プロトコル: レベル 1 プロトコルに基づいて、データ A を読み取るときに S ロックを追加する必要があります。読み取り後すぐに S ロックを解除すると、ダーティ データの読み取りの問題を解決できます。トランザクションがデータ A を変更する場合、レベル 1 のロック プロトコルに従って X ロックが追加され、その後 S ロックを追加できないため、ダーティ データは読み込まれません。 レベル 3 ロック プロトコル: レベル 2 プロトコルに基づいて、データを読み取るときに S ロックを追加する必要があり、S ロックはトランザクションが完了した後にのみ解放できます。S ロックは、A を読み取るときに他のトランザクションが A に X ロックを追加できないため、読み取り中のデータの変更を回避し、繰り返し不可能な読み取りの問題を解決できます。 8. InnoDBエンジンのロック実装MVCC マルチバージョン同時実行制御は、MySQL の innoDB ストレージ エンジンが分離レベルを実装するための特定の方法です。コミット読み取りと繰り返し読み取りの 2 つの分離レベルを実装するために使用できます。コミットされていない読み取り分離レベルでは常に最新のデータ行が読み取られますが、要件は非常に低く、MVCC を使用する必要がありません。 ロックのセクションで述べたように、ロックは複数のトランザクションが同時に実行されるときに発生する同時一貫性の問題を解決できます。実際のシナリオでは、読み取り操作が書き込み操作を上回ることが多いため、不要なロック操作を避けるために読み取り/書き込みロックが導入されます。たとえば、読み取りと書き込みは相互に排他的ではありません。読み取り/書き込みロックでは、読み取り操作と書き込み操作は依然として相互に排他的であり、MVCC は複数バージョンの考え方を使用します。書き込み操作は最新バージョンのスナップショットを更新し、読み取り操作は古いバージョンのスナップショットを読み取ります。相互排他関係はなく、これは CopyOnWrite に似ています。 MVCC では、トランザクションの変更操作 (DELETE、INSERT、UPDATE) によって、データ行にバージョン スナップショットが追加されます。ダーティ リードと非反復リードが発生する最も基本的な理由は、トランザクションが他のトランザクションからコミットされていない変更を読み取ることです。トランザクションが読み取り操作を実行する場合、ダーティ リードと非反復読み取りの問題を解決するために、MVCC ではコミットされたスナップショットのみを読み取ることができるように規定されています。もちろん、トランザクションはコミットされていない独自のスナップショットを読み取ることができますが、これはダーティ リードとは見なされません。 システム バージョン番号 SYS_ID: 増加する番号です。新しいトランザクションが開始されるたびに、システム バージョン番号は自動的に増加します。 トランザクション バージョン番号 TRX_ID: トランザクション開始時のシステム バージョン番号。 MVCC のマルチバージョンとは、Undo ログに保存されるスナップショットの複数のバージョンを指します。ログは、ロールバック ポインター ROLL_PTR を介してデータ行のすべてのスナップショットを接続します。 INSERT、UPDATE、および DELETE 操作ではログが作成され、トランザクション バージョン番号 TRX_ID が書き込まれます。 DELETE は特別な UPDATE と見なすことができ、DEL フィールドも 1 に設定されます。 閲覧ビュー MVCC は ReadView 構造を維持します。この構造には主に、現在のシステム内のコミットされていないトランザクションのリストと、リストの最小値と最大値が含まれます。 SELECT 操作を実行する場合、データ行スナップショットの TRX_ID と TRX_ID_MIN および TRX_ID_MAX の関係を使用して、データ行スナップショットが使用できるかどうかが判断されます。 TRX_ID < TRX_ID_MIN は、データ行のスナップショットが現在のすべてのコミットされていないトランザクションの前に変更されたため、使用できることを示します。 TRX_ID > TRX_ID_MAX は、トランザクションの開始後にデータ行スナップショットが変更されたため使用できないことを示します。 TRX_ID_MIN <= TRX_ID <= TRX_ID_MAX、分離レベルに応じて判断する必要がある コミットされた読み取り: TRX_ID が TRX_IDs リストにある場合、データ行スナップショットに対応するトランザクションがコミットされていないため、スナップショットを使用できないことを意味します。それ以外の場合は送信済みであり、使用できます。 繰り返し読み取り: どちらも使用できません。使用できる場合、他のトランザクションもこのデータ行のスナップショットを読み取って変更できるため、現在のトランザクションがこのデータ行を読み取ったときに取得した値が変更され、反復不可能な読み取りの問題が発生することを意味します。データ行のスナップショットが利用できない場合は、Undo ログのロールバック ポインター ROLL_PTR に従って次のスナップショットを見つけ、上記の判断を実行する必要があります。 スナップショット読み取りとセーフ読み取り スナップショット読み取り: MVCC の選択操作はスナップショット内のデータであり、ロック操作は必要ありません。 現在の読み取り: MVCCデータベースを変更するその他の操作では、最新のデータを読み取るためにロック操作が必要です。MVCCはロックを完全に回避するのではなく、選択のロック操作のみを回避することがわかります。 ロックを選択する必要がある場合は、前述の共有ロックや排他ロックなどのロック操作を強制することができます。 ネクストキーロック 概念: Next-Key Locks は、MySQL の InnoDB ストレージ エンジンのロック実装です。 MVCC ではファントム リードの問題を解決できませんが、この問題を解決するために Next-Key Locks が存在します。 REPEATABLE READ 分離レベルでは、MVCC + Next-Key Locks を使用するとファントム読み取りの問題を解決できます。 レコード ロック: レコード自体ではなく、レコードのインデックスをロックします。テーブルにインデックスがない場合、InnoDB は主キーに非表示のクラスター化インデックスを自動的に作成します。 ギャップ ロック: インデックス間のギャップをロックしますが、インデックス自体はロックしません。たとえば、トランザクションが次のステートメントを実行するとします: SELECT c FROM t WHERE c BETWEEN 10 and 20 FOR UPDATE; ネクストキー ロック: レコード ロックとギャップ ロックを組み合わせたもので、レコードのインデックスをロックするだけでなく、インデックス間のギャップもロックします。前方が開いていて後方が閉じている範囲をロックします。たとえば、インデックスに 10、11、13、20 という値が含まれている場合、次の範囲をロックする必要があります: (-∞、10](10、11](11、13](13、20](20、+∞) IX. 結論上記の理論は数多くありますが、研究開発プロセス全体をサポートしています。さまざまなビジネスシナリオに遭遇したとき、データベースの分離レベルに基づいて、トランザクションがデッドロック、データの不整合、およびその他の理論的な問題を引き起こすかどうかを判断する必要があります。 MySQL の最も強力な機能は、パフォーマンスとデータ セキュリティの両方を考慮した RR [Repeatable Read] レベルでファントム リードを回避することです。 これで、MySQL データベースのトランザクションとロックの詳細な分析に関するこの記事は終了です。MySQL データベースのトランザクションとロックに関するより関連性の高い情報については、123WORDPRESS.COM の以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。 以下もご興味があるかもしれません:
|
<<: ウェブサイトのデザインを改善するための役立つ提案を提供します
>>: CentOS 7.x dockerはoverlay2ストレージ方式を使用する
MySQL グリーンバージョン設定コードと 1067 エラーMySQL エンコーディングを表示 ...
mysql ログインのコマンド形式は次のとおりです。 mysql -h [hostip] -u [ユ...
まず効果図を見てみましょう: 完全なコードは添付されています <テンプレート> <...
この記事の例では、Vueスライダー検証の実装を共有しています。コードは次のとおりです。 <テン...
HTTP ステータス コードステータス コードは 3 桁の数字と理由フレーズ (最も一般的なもの: ...
123WORDPRESS.COM HTML チュートリアル セクションに戻るには、ここをクリックして...
導入MySQL InnoDB エンジンがレコードをクエリし、インデックス カバレッジを使用できない場...
目次間違い1: データの列が多すぎる誤解2: 共同クエリが多すぎる誤解3: ENUMの代わりにSET...
この記事では、クリックするとランダムグラフィックの生成を実現するJavaScriptの具体的なコード...
目次1. 関数デバウンス1. 画像安定化とは何ですか? 2. 関数のスロットリング2.1 タイマーの...
コンポジション継承組み合わせ継承は、疑似古典的継承とも呼ばれます。これは、昨日説明したプロトタイプ ...
開発中、MySQL へのリモートアクセスでよく問題に遭遇します。そのたびに検索する必要があり、面倒に...
Nginx は複数のサーバーをリバース プロキシします。つまり、nginx に異なるリクエストを送信...
フラットなウェブサイト構造の本質はシンプルさです。コンテンツの重要なポイントを強調し、ページの装飾効...
Linuxで環境変数を削除するには?unsetコマンドを使用してすぐに削除します1. Linuxクラ...