MySQLインタビューの「ロック」

人工知能、ゼロベースのエントリー!http://www.captainbed.net/inner 

1ロックとは

1.1ロックの概要

古代の単純なドアロックからパスワードロック、現在の指紋ロック解除や顔認識ロックまで、人生のロックの例はたくさんあります。これらはすべて明確なロックの例であるため、ロックは非常に単純である必要があることを理解しています。

MySQLのロックに目を向けると、MySQLの場合、ロックは非常に重要な機能です。データベースのロックは、共有リソースへの同時アクセスをサポートし、データの整合性と一貫性を提供して、高い同時実行性を確保することです。データベースにアクセスするときは、データに問題はありません。

1.2ロックの2つの概念

データベースでは、ロックとラッチの両方をロックと呼ぶことができますが、それらの意味は異なります。

ラッチは闩锁ロック時間が非常に短いため、一般に(軽量ロック)と呼ばれます。期間が長いと、アプリケーションのパフォーマンスが非常に低下します。InnoDBエンジンでは、ラッチはmutex(相互排除)とrwlock(読み取り/書き込みロック)に分けることができますその目的は、重要なリソースを操作する並行スレッドの正確性を確保することであり、通常、デッドロック検出メカニズムはありません。

Lockの目的は事务、テーブル、ページ、行など、データベース内のオブジェクトをロックすることです。また、通常、ロックオブジェクトは、トランザクションのコミットまたはロールバック後にのみ解放されます(解放時間は、トランザクションの分離レベルによって異なる場合があります)。

2InnoDBストレージエンジンのロック

2.1ロックの粒度

データベースでは、ロックの粒度をテーブルロック、ページロック、行ロックに分けることができます。これらのロックの粒度もアップグレードされます。ロックのアップグレードとは、現在のロックの粒度が低下することを意味します。データベースは、 table 1000行のロックをページロックにアップグレードするか、ページロックをテーブルロックにアップグレードします。これら3つのロックの粒度を以下に示します(ブログを参照してください:https://blog.csdn.net/baolingye/article/詳細/ 102506072)。

テーブルロック

テーブルレベルのロックは、MySQLストレージエンジンの中で最もきめ細かいロックメカニズムです。ロックメカニズムの最大の特徴は、実装ロジックが非常に単純であり、システムの悪影響が最小限であることです。したがって、ロックの取得と解放の速度は非常に高速です。テーブルレベルのロックはテーブル全体を一度にロックするため、私たちを悩ませているデッドロックの問題を回避できます。

もちろん、ロックの粒度が大きいことによってもたらされる最大の悪影響は、ロックされたリソースの競合の可能性も最も高くなり、大幅な割引が発生することです。

テーブルレベルのロックは、主にMyISAM、MEMORY、CSVなどの一部の非トランザクションストレージエンジンで使用されます。

特徴: オーバーヘッドが低く、ロックが高速で、デッドロックがない、ロックの粒度が大きい、ロックの競合の可能性が最も高い、同時実行性が最も低い。

ページロック

ページレベルのロックはMySQL独自のロックレベルであり、他のデータベース管理ソフトウェアではあまり一般的ではありません。ページレベルのロックの特徴は、ロックの粒度が行レベルのロックとテーブルレベルのロックの間にあることです。したがって、ロックを取得するために必要なリソースオーバーヘッドと、提供できる同時処理機能も上記の2つの間にあります。 。また、ページレベルのロックは行レベルのロックと同じであり、デッドロックが発生します。
データベースリソースのロックの過程で、ロックされたリソースの粒度が低下するにつれて、同じ量のデータをロックするために必要なメモリの量はますます多くなり、実装アルゴリズムはますます複雑になります。ただし、ロックされたリソースの粒度が低下すると、アプリケーションアクセス要求でロック待機が発生する可能性も低くなり、システムの全体的な同時実行性も向上します。
ページレベルのロックの主な用途は、BerkeleyDBストレージエンジンです。

特徴: オーバーヘッドとロック時間はテーブルロックと行ロックの間です。デッドロックが発生します。ロックの粒度はテーブルロックと行ロックの間であり、同時実行性は平均的です。

行ロック

行レベルのロックの最大の特徴は、ロックされたオブジェクトの粒度が非常に小さいことです。また、主要なデータベース管理ソフトウェアによって達成されるロックの最小の粒度でもあります。ロックの粒度が非常に小さいため、ロックされたリソースの競合の可能性も最小になります。これにより、アプリケーションに可能な限り多くの同時処理機能を提供し、一部の同時実行性の高いアプリケーションシステムの全体的なパフォーマンスを向上させることができます。

並行処理機能には大きな利点がありますが、行レベルのロックには多くの欠点もあります。ロックされたリソースの粒度は非常に小さいため、毎回ロックを取得および解放するために行うべきことが多く、消費量は当然大きくなります。さらに、行レベルのロックもデッドロックを起こしやすい傾向があります。

特徴:高い オーバーヘッドと遅いロック、デッドロックが発生する、最小のロック粒度、最小のロック競合の可能性、および最高の同時実行性。

テーブルロックを比較すると、これら2種類のロックの特性は基本的に逆であることがわかります。ロックの観点からは、テーブルレベルのロックは、に基づいてデータを更新するアプリケーションの数が少ないクエリ指向のアプリケーションに適しています。 Webアプリケーションなどのインデックス条件。行レベルのロックは、インデックス条件やオンライントランザクション処理(OLTP)などの同時クエリに応じて、少量の異なるデータを多数同時に更新するアプリケーションに適しています。システム。

さまざまなMySQLエンジンでサポートされているロックの粒度

 

2.2ロックの種類

InnoDBストレージエンジンにはさまざまなタイプのロックがあり、以下に1つずつ紹介します。

SまたはX(共有ロック、排他ロック)

実際には、読み取りと書き込みの2つのデータ操作しかなく、データベースがロックを実装する場合、これら2つの操作に異なるロックが使用されます。InnoDBは、共有ロック(共有ロック)である標準の行レベルのロックを実装します。排他ロック(排他ロック)

  • 共有ロック(読み取りロック)(Sロック)。トランザクションがデータの行を読み取ることができます。

  • 排他ロック(書き込みロック)(Xロック)。トランザクションがデータの行を削除または更新できるようにします。

ISまたはIX(共有、排他的)インテンションロック

行ロックとテーブルロックを共存させ、マルチグラニュラリティロックメカニズムを実装できるようにするために、InnoDBストレージエンジンは、意図的ロックと呼ばれる追加のロック方法をサポートします。意図的ロックは、InnoDBのテーブルレベルのロックです。意図的ロックは分割されます。に:

  • 意図的な共有ロック:トランザクションがテーブルの特定の行で共有ロックを取得することを望んでいることを表します。

  • インテント排他ロック:トランザクションがテーブルの特定の行で排他ロックを取得することを望んでいることを表します。

さらに、これらのロックは必ずしも相互に互換性があるとは限らず、一部のロックは互換性がありません。いわゆる互換性とは、トランザクションAが特定の行の特定のロックを取得した後、トランザクションBもこの行の特定の行を取得しようとすることを意味します。。一種のロック。すぐに取得できる場合はロック互換と呼ばれ、そうでない場合は競合と呼ばれます。

これら2つのロックの互換性を見てみましょう。

[1] SまたはXの互換性(共有ロック、排他ロック) 

[2] ISまたはIX(共有、排他的)インテントロックの互換性 

3前の要約

これは、マインドマップを使用した以前の概念の要約です。

 

4一貫した非ロック読み取りと一貫したロック読み取り

一貫性のあるロック読み取り

トランザクション内のデータをクエリする場合、通常のSELECTステートメントはクエリされたデータをロックせず、他のトランザクションはクエリされたデータに対して更新および削除操作を実行できます。したがって、InnoDBは、追加のセキュリティを確保するために2種類のロック読み取りを提供します。

【1】SELECT … LOCK IN SHARE MODE

【2】SELECT ... FOR UPDATE

【3】SELECT ... LOCK IN SHARE MODE:行を読み取るためにSロックを追加します。他のものは、これらの行にSロックを追加できます。Xロックを追加すると、ブロックされます。

【4】SELECT ... FOR UPDATE:クエリされた行と関連するインデックスレコードにXロックが追加され、他のトランザクションによって要求されたSロックまたはXロックがブロックされます。トランザクションがコミットまたはロールバックされると、これら2つのステートメントによって追加されたロックが解放されます。注:SELECT FOR UPDATEは、自動コミットが無効になっている場合にのみ行をロックできます。自動コミットがオンになっている場合、一致する行はロックされません。

一貫性のある非ロック読み取り

一貫性のある非ロック読み取り とは、InnoDBストレージエンジンが複数バージョン管理(MVVC)を介して現在のデータベースの行データを読み取る方法を指します。読み取り行がDELETEまたはUPDATE操作を実行している場合、読み取り操作は行ロックの解放を待機しません。逆に、InnoDBは行のスナップショットを読み取ります。したがって、非ロック読み取りメカニズムにより、データベースの同時実行性が大幅に向上します。

 

一貫性のある非ロック読み取りは、InnoDBのデフォルトの読み取りモードです。つまり、読み取りは行のロックを占有して待機しません。トランザクション分離レベルREAD COMMITTEDREPEATABLE READ低い、InnoDBが一貫した非ロックリードを使用します。

ただし、スナップショットデータの定義は異なります。READ COMMITTEDトランザクション分離レベル、一貫した非ロックは常に読み取りロックされた行の最新のスナップショットデータを読み出します下のREPEATABLE READトランザクション分離レベル、トランザクションの開始時に行データバージョンが読み取ります

簡単な例を使用して、これら2つの方法の違いを説明しましょう。

最初にテーブルを作成します。

データを挿入します。

insert into lock_test values(1);

分離レベルを表示します。

select @@tx_isolation;

以下は、操作する2つのタイプのトランザクションに分けられます。

下のREPEATABLE READトランザクション分離レベル:

 

下のREPEATABLE READトランザクション分離レベル、トランザクションの開始時に行データが読み出されるので、セッションBの修正後のデータは、データがまだ前のクエリを介して照会することができます。

下のREAD COMMITTEDトランザクション分離レベル:

下のREAD COMMITTEDトランザクション分離レベル、行バージョンの最新のスナップショットデータが読み出される。したがって、セッションBの修正データとがトランザクションをコミットするので、Aがデータを読み取ることができません。

5行ロックアルゴリズム

InnoDBストレージエンジンには、次の3つの行ロックアルゴリズムがあります。

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

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

[3] Next-Key Lock:Gap Lock + Record Lock、範囲をロックし、レコード自体をロックします。

レコードロック:常にインデックスレコードをロックします。InnoDBストレージエンジンテーブルが作成時にインデックスで設定されていない場合、InnoDBストレージエンジンは暗黙の主キーを使用してロックします。

Next-Key Lock:ギャップロックとレコードロックを組み合わせたロックアルゴリズム。Next-KeyLockアルゴリズムでは、InnoDBはこのロックアルゴリズムを行クエリに使用します。たとえば、10、20、30の場合、インデックスがNext-KeyLockingになる間隔は次のとおりです。

 

Next-Key Lockingに加えて、Previous-Key Lockingテクノロジーがあります。このテクノロジーは、Next-Key Lockの反対であり、ロックされた間隔は間隔範囲と前の値です。上記と同じ値の場合、Previous-Key Lockingテクノロジーを使用すると、ロック可能な間隔は次のようになります。 

すべてのインデックスがネクストキーロックを追加するわけではありません。特別な場合があります。クエリ列が一意のインデックス(主キーインデックスを含む)の場合、にNext-key LockダウングレードされRecord Lockます。

次に、例を通して説明しましょう。

CREATE TABLE test (
    x INT,
    y INT,
    PRIMARY KEY(x),    // x是主键索引
    KEY(y)    // y是普通索引
);
INSERT INTO test select 3, 2;
INSERT INTO test select 5, 3;
INSERT INTO test select 7, 6;
INSERT INTO test select 10, 8;

ここで、セッションAで次のステートメントを実行します。

SELECT * FROM test WHERE y = 3 FOR UPDATE

このときのロック状況を分析してみましょう。

[1]主キーxの場合

[2]補助インデックスy

ユーザーは、次の2つの方法でギャップロックを表示できます。

  • トランザクションの分離レベルをREADCOMMITEDに設定します。

  • パラメータinnodb_locks_unsafe_for_binlogを1に設定します。

ギャップロックの機能は、複数のトランザクションが同じ範囲にレコードを挿入するのを防ぐことです。これは、フォントム問題(ファントム読み取り問題)を解決するように設計されています。MySQLのデフォルトの分離レベル(Repeatable Read)では、InnoDBはそれを使用してファントム読み取りの問題を解決します。

ファントム読み取り:同じトランザクションで、同じSQLステートメントを2回連続して実行すると、異なる結果が生じる可能性があることを意味します.2番目のSQLは、以前に存在しなかった行、つまり最初の実行と2番目の実行中に別のトランザクションを返す場合がありますその中に新しい行を挿入しました。

6ロックによる問題

6.1ダーティリード

ダーティ読み取り: さまざまなトランザクションで、現在のトランザクションが別のトランザクションのコミットされていないデータを読み取ることができます。さらに、デフォルトのMySQL分離レベルに注意する必要REPEATABLE READがあります。ダーティ読み取りは発生しません。ダーティ読み取りが発生する条件はトランザクションの分離レベルであるREAD UNCOMMITTEDため、ダーティ読み取りが発生した場合は、この分離が原因である可能性があります。レベル。

例を通してそれを見てみましょう。

 上記の例からわかるように、トランザクションの分離レベルがである場合READ UNCOMMITTED、セッションA、セッションAが送信される前にセッションAによって送信されていないデータをクエリできます。

6.2繰り返し不可の読み取り

繰り返し不可の読み取り: トランザクションで同じデータセットを複数回読み取ることを指しますが、複数回読み取られるデータは異なり、データベーストランザクションの一貫性の原則に違反します。ただし、これはダーティ読み取りとは異なります。ダーティ読み取りデータは送信されませんが、繰り返し不可の読み取りデータは送信されたデータです。

この種の問題の発生を次の例で見てみましょう。

上記の例からわかるように、Aのセッションでは、セッションBがデータを挿入するため、2つのクエリの結果に一貫性がなく、読み取りが繰り返されないという問題があります。

注意が必要なのは、繰り返し不可能な読み取りデータは送信されたデータであり、トランザクションの分離レベルはであるということですREAD COMMITTED。この種の問題は許容できます。

繰り返し不可能な読み取りの問題の発生を回避する必要がある場合は、Next-Key Lockアルゴリズム(トランザクション分離レベルをに設定READ REPEATABLE)を使用してそれらを回避できます。MySQLでは、繰り返し不可能な読み取りの問題はファントム問題です。つまり、ファントム問題です。

6.3失われた更新

失われた更新:あるトランザクションの更新操作が別のトランザクションの更新操作によって上書きされ、データの不整合が発生することを指します。現在のデータベースの分離レベルでは、更新の喪失の問題は発生しません。この問題が発生した場合、この問題はマルチユーザーコンピューターシステム環境で発生する可能性があります。

更新が欠落する問題を回避する方法としては、トランザクション操作をシリアル化するだけでよく、並列実行は必要ありません。

通常、SELECT ... FOR UPDATEステートメントを使用して、操作に排他的なXロックを追加します。

6.4まとめ

ここでは、主にさまざまなトランザクションの分離レベルで発生する問題を比較するために要約を作成し、より明確にします。

 

おすすめ

転載: blog.csdn.net/qq_35860138/article/details/102677920