検索
ホームページデータベースSQLMySQL トランザクションと MVCC によって達成される分離レベルについて話しましょう

この記事では、MySQL トランザクションの分離レベルと MVCC による分離レベルの実装方法に関連するいくつかの問題について説明します。

MySQL トランザクションと MVCC によって達成される分離レベルについて話しましょう

#データベース トランザクションの概要

トランザクションの 4 つの主要な特徴 (ACID)

  1. 原子性: トランザクションの最小作業単位。すべてが成功したか、すべてが失敗したか。

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

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

  4. 耐久性 (耐久性): トランザクションが送信された後のデータへの変更は永続的であり、システムに障害が発生した場合でも失われることはありません。

トランザクションの分離レベル

UnCommitted/RU

を再び読み取ります。

dirtyと呼ばれます。 reading では、あるトランザクションはコミットされていないデータを別のトランザクションから読み取ることができます。コミットされていないトランザクションはロールバックされる可能性があるため、この分離レベルは最も安全性が低くなります。

Read Committed/RC

Non-repeatable read とも呼ばれる、トランザクションが別のトランザクションを読み取りました。送信された変更されたデータにより、一貫性のない結果が生じます。現在のトランザクションの異なる時点で同じデータを読み取ることによって取得されます。

たとえば、次の例では、SessionA がトランザクション中に異なるデータを 2 回クエリしていることがわかります。その理由は、現在の分離レベルが RC であり、セッション A のトランザクションはセッション B によって送信された最新データを読み取ることができるためです。

#発生時刻セッション Aセッション B12select * from user where id=1;(张三)34select * from user where id =1 ;(李思)ユーザー セット名 = ' Wang Er' を更新where id=1;(デフォルトの暗黙的トランザクションコミット)select * from user where id=1;(Wang Er)##Repeatable Read/RR
begin;

update user set name='李思' where id=1; (デフォルトの暗黙的コミットトランザクション)

5

6

ファントム読み取り とも呼ばれるトランザクション読み取りは、他のトランザクションによって送信されたデータですが、RR 分離レベルでは、このデータの現在の読み取りは 1 回しか読み取ることができません。現在のトランザクションでは、何度読み取られても、データは依然として、そのトランザクションに対して読み取られた値です。最初の読み取り後に他のトランザクションがこのデータを変更して送信するため、変更されません。したがって、読み出されるデータが必ずしも最新のデータであるとは限らず、ファントムリードともなります。

例: セッション A で初めてデータが読み取られるとき、送信されたデータを変更する後続のトランザクションは、セッション A によって読み取られるデータ値に影響を与えません。これは

繰り返し読める読書 です。

#発生時刻

セッション Aセッション Bbegin;select * from user where id=1;(张三)update user set name='李思' where id=1; (デフォルトの暗黙的トランザクション送信)select * from user where id =1 ;(Zhang San)##5ユーザー セット名 = ' Wang Er' を更新where id=1; (デフォルトの暗黙的なトランザクション送信)6
1
2
3
4


select * from user where id=1;(Zhang San)
#シリアル化可能
データベースの読み取りまたは書き込み操作はすべてシリアル行実行であり、現在の分離レベルは同時実行のみをサポートしています。すべての操作はキューの実行を必要とします。したがって、この分離レベルにあるすべてのデータは最も安定していますが、パフォーマンスも最悪になります。データベースのロック実装は、この分離レベルのより粒度が小さいバージョンです。

#発生時刻

セッション A

セッション B
1 begin;
2
#begin;
3
ユーザー セット名を更新='李四' where id=1;
4 select * from user where id=1;(待て、待て)
5
コミット;
6 選択* id=1 のユーザーから;(李思)

トランザクションと MVCC の原則

同じデータを同時に操作する異なるトランザクションによって引き起こされる問題

例:

##1begin;##23456現金で 100 元を引き出し、残高は 900 元に修正されます89 ##トランザクションのコミット (残高=1100) 900)
#発生時間 セッションA セッションB


begin;

残高確認 = 1,000 元
残高確認 = 1,000 元
##入金額は 100 元で、修正残高は 1100 元です

トランザクションをコミット (残高=1100)

#発生時刻##1開始;##開始;お問い合わせ残高 = 1,000 元お問い合わせ残高 = 1,000 元入金額は 100 元、修正残高は 1100 元です現金 100 元を引き出し、残高は 900 元に修正されます取引を送信 (残高 = 1100) ##9

上記の 2 つの状況は、複数のトランザクションが 1 つのデータに対して同時に動作する場合に発生する可能性がある問題で、特定のトランザクションの動作が上書きされ、データが失われる可能性があります。

LBCC はデータ損失を解決します

LBCC、ロックベースの同時実行制御。

ロック メカニズムを使用すると、現在のトランザクションがデータを変更する必要がある場合、現在のトランザクションはロックされます。現在のデータを同時に変更できるのは 1 つのトランザクションだけであり、他のトランザクションは待機する必要があります。ロックを解除するための操作を行います。

MVCC はデータ損失を解決します

MVCC、マルチバージョン同時実行制御、マルチバージョン同時実行制御。

バージョンを使用して同時実行状況でのデータの問題を制御します。トランザクション B がアカウントの変更を開始し、トランザクションが送信されないとき、トランザクション A がアカウント残高を読み取る必要がある場合、トランザクション B は次の時点で読み取られます。操作の前に口座残高のコピー データを変更しますが、トランザクション A が口座残高データを変更する必要がある場合、トランザクション B がトランザクションをコミットするまで待つ必要があります。

MVCC を使用すると、データをロックせずにデータベースを読み取り、ロックせずに通常の SELECT リクエストを実行できるようになり、データベースの同時処理能力が向上します。 MVCC の助けを借りて、データベースは READ COMMITTED や REPEATABLE READ などの分離レベルを実装できます。ユーザーは現在のデータの前または以前の履歴バージョンを表示して、ACID の I 機能 (分離) を確保できます。

InnoDB の MVCC 実装ロジック

InnoDB ストレージ エンジンによって保存される MVCC データ

InnoDB の MVCC は、各行の非表示列が実装された後に 2 つのレコードを保存します。 行を保存するトランザクション ID (DB_TRX_ID)、および行 を保存するロールバック ポインター (DB_ROLL_PT)。新しいトランザクションが開始されるたびに、新しいトランザクション ID が自動的に増加します。トランザクションの開始時に、トランザクション ID は、現在のトランザクションの影響を受ける行トランザクション ID に配置されます。クエリを実行する場合、現在のトランザクション ID と各行に記録されているトランザクション ID を比較する必要があります。

REPEATABLE READ 分離レベルで MVCC がどのように動作するかを見てみましょう。

SELECT

InnoDB は、次の 2 つの条件に従ってレコードの各行をチェックします。

  1. InnoDB はバージョンのみを検索します。現在のものよりも前のデータ行のトランザクション バージョン (つまり、行のトランザクション番号が現在のトランザクションのトランザクション番号以下であること)。これにより、トランザクションによって読み取られる行が以前にすでに存在していることが保証されます。トランザクションが開始されるか、トランザクション自体によって挿入または変更された。

  2. 削除された行は、トランザクション ID とトランザクションを読み取る前の状態のバージョンによって判断する必要があり、上記 2 つの条件を満たすレコードのみがクエリ結果として返されます。 。

INSERT

InnoDB は、新しく挿入された各行の行バージョン番号として現在のトランザクション番号を保存します。

DELETE

InnoDB は、削除された各行の行削除 ID として現在のトランザクション番号を保存します。

UPDATE

InnoDB は、新しいレコード行を挿入し、現在のトランザクション番号を行のバージョン番号として保存し、現在のトランザクション番号を元の行に行削除識別子。

ほとんどの読み取り操作をロックせずに実行できるように、これら 2 つの追加トランザクション番号を保存します。この設計により、データ読み取り操作が非常にシンプルになり、パフォーマンスが非常に向上し、また、規格を満たす行のみが確実に読み取られるようになります。欠点は、レコードの各行に追加の記憶域スペース、より多くの行チェック、および追加のメンテナンス作業が必要になることです。

MVCC は、REPEATABLE READ と READ COMMITIED の 2 つの分離レベルでのみ機能します。 READ UNCOMMITIED は、現在のトランザクション バージョンに準拠するデータ行ではなく、常に最新のデータ行を読み取るため、他の 2 つの分離レベルは MVCC と互換性がありません。 SERIALIZABLE は、読み取られたすべての行をロックします。

mysql での MVCC の実装は、アンドゥ ログと読み取りビューに依存しています。

アンドゥ ログ

さまざまな動作に応じて、アンドゥ ログは アンドゥ ログの挿入アンドゥ ログの更新#の 2 つのタイプに分類されます。

  • ##insert undo log:

# 挿入操作のみが記録されるため、挿入操作中に生成される元に戻すログ現在のトランザクション自体の場合、このレコードは他のトランザクションには表示されないため、トランザクションがコミットされた後、パージ操作を実行せずに挿入取り消しログを直接削除できます。

パージの主なタスクは、データベース内で del マークが付けられたデータを削除することです。さらに、元に戻すページもバッチでリサイクルします。

最初のデータベース挿入時のデータの状態:

  • 更新取り消しログ:

    更新または削除操作中に生成された取り消しログ。既存のレコードに影響を与えるため、MVCC メカニズムを提供するために、更新取り消しログはトランザクションの送信時に削除できません。代わりに、トランザクションの送信時に履歴リストに配置され、パージ スレッドが実行されるのを待ちます。最後の削除操作。

    データが初めて変更されるとき:

別のトランザクションが現在のデータを 2 回目に変更するとき:

同時トランザクション操作中にそれぞれの UNDO ログを書き込むときに競合が発生しないようにするために、InnoDB はロールバック セグメントを使用して同時書き込みと UNDO ログの永続性を維持します。ロールバック セグメントは、実際には Undo ファイルを整理する方法です。

読むビュー

RU(READ UNCOMMITTED) 分離レベルの場合、すべてのトランザクションはデータベースの最新の値を直接読み取ることができ、SERIALIZABLE 分離レベルの場合、すべてのリクエストはロックされ、同期的に実行されます。したがって、これら 2 つのケースでは、Read View のバージョン管理を使用する必要はありません。

RC(READ COMMITTED) および RR(REPEATABLE READ) の場合、分離レベルは上記のバージョン管理によって実装されます。 2 つの分離セクターの下での中心的な処理ロジックは、すべてのバージョンのうちのどのバージョンが現在のトランザクションに表示されるかを決定することです。この問題を解決するために、InnoDB は ReadView デザインをデザインに追加しました。ReadView には主に現在のシステム内のアクティブな読み取りおよび書き込みトランザクションが含まれており、それらのトランザクション ID をリストに入れます。 . 、このリストに m_ids という名前を付けます。

クエリ時にバージョンチェーンデータが表示されるかどうかの判定ロジック:

  • アクセスされたバージョンの trx_id 属性値が m_ids 内の最小のトランザクション ID より小さい場合このバージョンのトランザクションは ReadView を生成する前にコミットされているため、現在のトランザクションからこのバージョンにアクセスできることを示します。

  • アクセスされたバージョンの trx_id 属性値が m_ids リスト内の最大のトランザクション ID より大きい場合、このバージョンを生成したトランザクションが ReadView の生成後に生成されたことを示します。したがって、このバージョンは現在のトランザクション アクセスでは使用できません。

  • アクセスされたバージョンの trx_id 属性値が m_ids リスト内の最大のトランザクション ID と最小のトランザクション ID の間にある場合は、trx_id 属性値がm_ids リスト。そうである場合は、ReadView の作成時にこのバージョンを生成したトランザクションがまだアクティブであり、このバージョンにアクセスできないことを意味します。そうでない場合は、ReadView の作成時にこのバージョンを生成したトランザクションがコミットされたことを意味します、このバージョンにアクセスできます。

例:

分離レベルでの READ COMMITTED ReadView

データを読み取るたびに、すべてがReadView (m_ids リスト)

セッションA セッションB
2
#3
4
5
6
8

取引をキャンセル (残高は 1000 元に回復) )
##T1 begin;T2T3#T4##...UPDATE ユーザー SET name = 'Messi' WHERE id = 1;SELECT * FROM user where id = 1;#コミット;#UPDATE ユーザー セット名 = 'Neymar' WHERE id = 1;##T8 #SELECT * FROM user where id = 1;##UPDATE ユーザー セット名 = 'Dybala' WHERE id = 1;T10#SELECT * FROM user where id = 1;

これは、上記の状況における ReadView の分析です。

時点 T5 での SELECT ステートメント:

現時点でのバージョン チェーン:

This SELECT 文を実行すると現在のデータバージョンチェーンは上記の通り 現在のトランザクション 777 とトランザクション 888 が送信されていないため、この時点でアクティブなトランザクションの ReadView のリスト m_ids: [777, 888]、したがって、クエリ ステートメントは、現在のバージョン チェーン内の m_ids 未満の最大のバージョン データに基づきます。つまり、Mbappe がクエリされます。

時点 T8 の SELECT ステートメント:

現時点でのバージョン チェーンの状況:

この時点で SELECT ステートメントが実行されます。現在のトランザクション 777 は送信され、トランザクション 888 は送信されていないため、チェーンは上記のとおりです。したがって、この時点でアクティブなトランザクションの ReadView のリスト m_ids: [888] であるため、クエリ ステートメントは m_ids の最大バージョン データよりも小さいチェーンの現在のバージョンに基づきます。つまり、メッシがクエリされます。

時点 T11 の SELECT ステートメント:

現時点でのバージョン チェーン情報:

この時点で SELECT ステートメントが実行され、現在のデータ バージョン チェーンは上記の通りです。現在のトランザクション 777 とトランザクション 888 が送信されているため、この時点でアクティブなトランザクションの ReadView リストは空であるため、クエリ ステートメントは現在のデータベースの最新データを直接クエリします。つまり、ディバラは尋問される。

概要: READ COMMITTED 分離レベルを使用するトランザクションは、各クエリの開始時に独立した ReadView を生成します。

#REPEATABLE READ 分離レベルの ReadView

#トランザクション開始後の最初のデータ読み取り時に ReadView (m_ids リスト) を生成します

Time トランザクション 777 トランザクション 888 トランザクション 999



##開始;
begin;
UPDATE ユーザー SET 名 = 'CR7' WHERE ID = 1;



T5

T6

##T7



T9


#コミット;
##T11

#時間T1begin;開始;#T3UPDATE ユーザー セット名 = 'CR7' WHERE ID = 1;##T4...T5コミット;UPDATE ユーザー SET name = 'Neymar' WHERE id = 1;#T8T9UPDATE user SET名前 = 'ディバラ' WHERE id = 1;T10コミット;## SELECT * FROM user where id = 1;m_ids の内容は [777,888] であるため、ReadView の表示可能なバージョンに基づいてクエリされるデータは Mbappe です。
トランザクション 777 トランザクション 888 #トランザクション 999


T2

開始;




UPDATE ユーザー SET name = 'Messi' WHERE id = 1;
##SELECT * FROM user where id = 1; T6
##T7



SELECT * FROM user where id = 1;




##T11


#SELECT ステートメント (時点 T5):
現在のバージョン チェーン:
A ReadView は、時点 T5 で生成されます。 select ステートメントが現在実行されています。この時点で、

時点 T8 の SELECT ステートメント:

現在のバージョン チェーン:

現在のトランザクション 999 トランザクション。 ReadView は時点 T5 で生成されているため、ReadView は現在のトランザクションで 1 回だけ生成されるため、T5 の m_id はこの時点でもまだ使用されています: [777,999]、つまりこの時点のクエリ データまだムバッペだ。

時点 T11 の SELECT ステートメント:

現在のバージョン チェーン:

この時点の状況は T8 とまったく同じです。 ReadView は時点 T5 で生成されているため、ReadView は現在のトランザクションで 1 回だけ生成されるため、T5 の m_id はこの時点でもまだ使用されています: [777,999]、つまりこの時点のクエリ データまだムバッペだ。

MVCC の概要:

いわゆる MVCC (Multi-Version Concurrency Control、マルチバージョン同時実行制御) とは、

の使用を指します。 READ COMMITTDREPEATABLE READ

これら 2 つの分離レベルのトランザクションは、通常の SEELCT 操作の実行時に記録されたバージョン チェーンにアクセスするため、
読み取り-書き込み

書き込み-読み取り システムのパフォーマンスを向上させるために、操作は同時に実行されます。

推奨学習: mysql ビデオ チュートリアル

以上がMySQL トランザクションと MVCC によって達成される分離レベルについて話しましょうの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明
この記事はCSDNで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。
SQL:コマンド、mysql:エンジンSQL:コマンド、mysql:エンジンApr 15, 2025 am 12:04 AM

SQLコマンドは、DQL、DDL、DML、DCL、TCLのMySQLの5つのカテゴリに分割され、データベースデータの定義、操作、制御に使用されます。 MySQLは、語彙分析、構文分析、最適化、実行を通じてSQLコマンドを処理し、インデックスとクエリオプティマイザーを使用してパフォーマンスを向上させます。使用法の例には、データクエリの選択を選択し、マルチテーブル操作に参加します。一般的なエラーには、構文、ロジック、パフォーマンスの問題、および最適化戦略には、インデックスの使用、クエリの最適化、適切なストレージエンジンの選択が含まれます。

データ分析のためのSQL:ビジネスインテリジェンスの高度な手法データ分析のためのSQL:ビジネスインテリジェンスの高度な手法Apr 14, 2025 am 12:02 AM

SQLの高度なクエリスキルには、複雑なデータ分析要件を処理できるサブクエリ、ウィンドウ関数、CTE、複雑な結合が含まれます。 1)サブクエリは、各部門で最高の給与を持つ従業員を見つけるために使用されます。 2)ウィンドウ関数とCTEを使用して、従業員の給与成長傾向を分析します。 3)パフォーマンス最適化戦略には、インデックスの最適化、クエリの書き換え、パーティションテーブルの使用が含まれます。

MySQL:SQLの特定の実装MySQL:SQLの特定の実装Apr 13, 2025 am 12:02 AM

MySQLは、標準のSQL関数と拡張機能を提供するオープンソースリレーショナルデータベース管理システムです。 1)MySQLは、制限句の作成、挿入、更新、削除、拡張などの標準のSQL操作をサポートしています。 2)InnodbやMyisamなどのストレージエンジンを使用しています。これらは、さまざまなシナリオに適しています。 3)ユーザーは、テーブルの作成、データの挿入、ストアドプロシージャの使用など、高度な機能を介してMySQLを効率的に使用できます。

SQL:すべての人がデータ管理にアクセスできるようにしますSQL:すべての人がデータ管理にアクセスできるようにしますApr 12, 2025 am 12:14 AM

sqlmakesdatamanagemagementisibletoallbyproviding asimpleyetpowerfultoolset andmanagingdatabases.1)itworks withersortifyify what what what what what what what what whatysortsopecifyifyを許可します

SQLインデックス戦略:クエリパフォーマンスを桁違いに改善するSQLインデックス戦略:クエリパフォーマンスを桁違いに改善するApr 11, 2025 am 12:04 AM

SQLインデックスは、巧妙なデザインを通じてクエリパフォーマンスを大幅に改善できます。 1. Bツリー、ハッシュ、フルテキストインデックスなどの適切なインデックスタイプを選択します。 2。複合インデックスを使用して、マルチフィールドクエリを最適化します。 3.オーバーインデックスを避けて、データメンテナンスのオーバーヘッドを減らします。 4.不要なインデックスの再構築や削除など、定期的にインデックスを維持します。

SQLで制約を削除する方法SQLで制約を削除する方法Apr 10, 2025 pm 12:21 PM

SQLの制約を削除するには、次の手順を実行します。削除する制約名を特定します。 ALTER TABLEステートメントを使用してください:Table Table Name Drop Constraint Constraint Nameを変更します。削除を確認します。

SQLトリガーを設定する方法SQLトリガーを設定する方法Apr 10, 2025 pm 12:18 PM

SQLトリガーは、特定のイベントが指定されたテーブルで実行されたときに特定のアクションを自動的に実行するデータベースオブジェクトです。 SQLトリガーをセットアップするには、トリガー名、テーブル名、イベントタイプ、トリガーコードを含むCreate Triggerステートメントを使用できます。トリガーコードは、ASキーワードを使用して定義され、SQLまたはPL/SQLステートメントまたはブロックが含まれます。トリガー条件を指定することにより、Where句を使用して、トリガーの実行範囲を制限できます。トリガー操作は、インサート、更新、または削除ステートメントを使用してトリガーコードで実行できます。新しいキーワードと古いキーワードを使用して、トリガーコードの影響を受けるキーワードを参照できます。

SQLクエリのインデックスを追加する方法SQLクエリのインデックスを追加する方法Apr 10, 2025 pm 12:15 PM

インデックス作成は、データ列を並べ替えてデータ検索を加速するデータ構造です。 SQLクエリにインデックスを追加する手順は次のとおりです。インデックス化する必要がある列を決定します。適切なインデックスタイプ(Bツリー、ハッシュ、またはビットマップ)を選択します。 Create Indexコマンドを使用して、インデックスを作成します。インデックスを定期的に再構築または再編成して、その効率を維持します。インデックスの追加の利点には、クエリパフォーマンスの改善、I/O操作の削減、最適化された並べ替えとフィルタリング、および並行性の改善が含まれます。クエリが特定の列を使用することが多い場合、ソートまたはグループ化する必要がある大量のデータを返し、大きい複数のテーブルまたはデータベーステーブルが含まれます。インデックスの追加を検討する必要があります。

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser は、オンライン試験を安全に受験するための安全なブラウザ環境です。このソフトウェアは、あらゆるコンピュータを安全なワークステーションに変えます。あらゆるユーティリティへのアクセスを制御し、学生が無許可のリソースを使用するのを防ぎます。

SublimeText3 Linux 新バージョン

SublimeText3 Linux 新バージョン

SublimeText3 Linux 最新バージョン

MantisBT

MantisBT

Mantis は、製品の欠陥追跡を支援するために設計された、導入が簡単な Web ベースの欠陥追跡ツールです。 PHP、MySQL、Web サーバーが必要です。デモおよびホスティング サービスをチェックしてください。

WebStorm Mac版

WebStorm Mac版

便利なJavaScript開発ツール