ホームページ  >  記事  >  データベース  >  MySQL のインテント共有ロック、インテント排他ロック、デッドロックとは何ですか?

MySQL のインテント共有ロック、インテント排他ロック、デッドロックとは何ですか?

WBOY
WBOY転載
2023-05-27 22:22:021471ブラウズ

    1. InnoDB テーブル レベルのロック

    行レベルのロックは通常、トランザクションの整合性を確保するために使用する必要があり、これも一般的な理由です。 InnoDB エンジンを選択するための 1 つ。ただし、個々のケースでは、テーブルレベルのロックも必要になる場合があります。

    トランザクションは大部分またはすべてのデータを更新する必要があり、テーブルは比較的大きいです。デフォルトの行ロックが使用されている場合、トランザクションの実行効率が低いだけでなく、他のトランザクションが発生する可能性があります。長時間待機し、ロックの競合が発生します。トランザクションには複数のテーブルが含まれます。これはより複雑で、デッドロックや多数のトランザクションのロールバックを引き起こす可能性があります。

    取得したい場合テーブル ロックを取得するには、次のコマンドを実行します。

    MySQL のインテント共有ロック、インテント排他ロック、デッドロックとは何ですか?

    テーブル ロックを使用する場合、効率の問題が発生します。
    共有ロックを取得するにはテーブルに S または排他ロック X を設定する場合は、まずテーブルが他のトランザクションによって取得されていないことを確認する必要があります。X ロックの後、このテーブルのデータは他のトランザクションによって取得されていません。

    このテーブルに 1,000 万のデータがあると仮定します。これらの 1,000 万のデータのどの行に X ロックがあるかをどのように判断するのでしょうか?
    テーブルの S ロックを取得したい場合は、テーブル内のどの行が X ロックを持つかを決定する必要があります。一部の行に X ロックがある場合、このテーブルの S ロックまたは X ロックを取得することはできません。 1 つずつチェックする以外に良い方法はありませんが、これは効率が悪いという問題につながります。行ロックが追加されましたが、問題はほとんどありません。ここで学習しているインテンション共有ロックとインテンション排他ロックは解決できます。

    テーブルの X ロックを取得したいときに、テーブル内のどの行ロックが (X または S によって占有されているか) を確認する必要がなくなりました。 )、IX をすばやく確認するだけで済みます。IS

    でロックするだけです。 2. インテンション共有ロックとインテンション排他ロック

    • インテンション共有ロック (IS ロック):

      トランザクション プランはレコードに行共有ロックを追加します。 、トランザクションがレコードの行に共有ロックを追加する前に、まずテーブル

    • 意図排他ロック (IX ロック):

      の IS ロックを取得する必要があります。トランザクション プランは、IS ロック行排他ロックにレコードを追加します。トランザクションは行レコードに排他ロックを追加する前に、まずテーブル

    # の IX ロックを取得する必要があります。

    MySQL のインテント共有ロック、インテント排他ロック、デッドロックとは何ですか?

    • 行ロックを追加する前に、InnoDB ストレージ エンジンによって追加されたテーブルの IS または IX ロック

    • 意図ロックは
    • 互換性

      です。競合はありません。これは主に、他のユーザーがテーブル ロックを取得する際の効率を上げるのを支援するためです。

    • インテンション ロックの目的は次のとおりです。テーブル ロックをより効率的に取得するため (テーブル S の X と X は、行ロックではなく
    • テーブル ロック

      を指します!)

    • 意図ロックは
    • table-レベル ロック

      はテーブル ロックと行ロックの共存 を調整します。主な目的は、トランザクションが行をロックしているか、または行をロックしようとしていることを示すことです。

    トランザクション 1 を分析して行 X のロックを取得し、トランザクション 2 を分析してテーブル S のロックを取得します。

    トランザクション 1 がテーブルへのデータの 10 行目 X ロックを追加すると、InnoDB ストレージ エンジンはテーブル全体に IX ロックを自動的に追加します。トランザクション 2 がテーブル全体の S ロックを取得しようとすると、別のトランザクションがこのテーブルの IX ロックを取得したことがわかります。これは、このテーブルには X ロックに追加されたデータが存在する必要があることを意味します。その結果、トランザクション 2 では、テーブル全体に S ロックを追加できません。現時点では、トランザクション 2 は待機することしかできず、テーブル S ロックを正常に取得できません。 ロック

    3. デッドロック

    1. データベース内のデッドロック

    MyISAMテーブルロックはデッドロックフリーです。これは、

    MyISAM はトランザクションをサポートせず、テーブル ロックのみをサポートしているためです。必要なすべてのロックを常に一度に取得し、すべてが満たされるか待機するため、デッドロック

    は発生しません。しかし、InnoDB では、単一の SQL で構成されるトランザクションを除き、徐々にロックが取得される、つまりロックの粒度が比較的小さいため、InnoDB ではデッドロックが発生する可能性があると判断されます。もちろん、複数のテーブルが処理される場合でもデッドロックが発生する可能性があります。 デッドロックの問題は通常、私たち自身によって引き起こされます。マルチスレッド プログラミングにおけるデッドロックの状況と同様に、そのほとんどは、複数のスレッドが複数のロック リソースを取得する順序の違いによって引き起こされ、その結果、デッドロックの問題が発生します。したがって、異なるコード セグメントを使用してデータベース内の複数のテーブルを更新する場合は、ロックの競合によってデッドロックの問題が発生するのを防ぐために、これらのテーブルを同じ順序で更新する必要があります。

    2. デッドロックのシナリオと解決策

    デッドロックのシナリオは次のとおりです:

    トランザクション 1 は行ロックを正常に取得しました 1

    トランザクション 2 は正常に取得されました行ロック 2

    ....
    トランザクション 1 は行ロック 2 を取得できませんでした。ブロックされている間、コミット/ロールバックを実行する方法がなく、行ロック 1
    トランザクション 2 を解放できませんでした。行ロック 1 を取得しようとしてブロックされました。ブロック中にコミット/ロールバックを実行する方法はなく、行ロックを解放できません。2

    MySQL のインテント共有ロック、インテント排他ロック、デッドロックとは何ですか?すべてのトランザクションがブロックされ、これは、プロセス内のすべてのスレッドがブロックされ、デッドロックの問題が発生するのと同じです。

    デッドロックを解決する方法: 複数のトランザクション/スレッドが複数の同じリソース ロックを取得する場合、同じ順序でリソース ロックを取得する必要があります。

    トランザクションがブロックまたはデッドロックされています。Mysqld (MySQL Server デーモン) には、トランザクション ブロックの タイムアウト期間が設定されています。トランザクションは長時間ブロックされず、トランザクションはタイムアウト後に処理され、失敗すると、現在保持されているロックが自動的に解放されます。

    3. 操作

    手動コミットと反復可能な読み取り分離レベルを設定し、トランザクションを開く

    MySQL のインテント共有ロック、インテント排他ロック、デッドロックとは何ですか?

    テーブル データを反復可能な形式でクエリします。分離レベルは MVCC によって提供されるスナップショット読み取りを使用し、ロックは行いません。

    MySQL のインテント共有ロック、インテント排他ロック、デッドロックとは何ですか?

    トランザクション 1 は id=7 で排他ロックを取得し、トランザクション 2 は id= で排他ロックを取得します。 8.

    MySQL のインテント共有ロック、インテント排他ロック、デッドロックとは何ですか?

    トランザクション 1 が再度 id=8 の排他ロックを取得し、ブロッキングが発生します。

    MySQL のインテント共有ロック、インテント排他ロック、デッドロックとは何ですか?

    トランザクション 2 が取得します。 id= again The exclusive lock of 7 is block.

    MySQL のインテント共有ロック、インテント排他ロック、デッドロックとは何ですか?

    この時点で、MySQL Server はデッドロックが発生したことを検出するため、トランザクション 1 のブロックを解除し、トランザクション 1 をロールバックし、行ロックが占有されているため、トランザクション 2 は id=7

    3 の排他ロックを正常に取得しました。ロック最適化の提案

    • ビジネスができるという前提の下で、効率を確保するには、より低い分離レベルを使用してみてください (ダーティ リードは回避する必要があります)

    • 合理的なインデックスを設計し、使用してみてください。データにアクセスするためのインデックス、ロックの正確性を高め、ロック競合の可能性を減らし、同時実行機能を向上させます

    • ##適切なトランザクション サイズを選択します。小規模なトランザクションでのロック競合の可能性小さい (トランザクションが大きくなるほど、トランザクション サイズも大きくなります。SQL の数が増えると、テーブル リソースと行リソースに対してより多くのロックが含まれる可能性があり、ロックの競合が発生する可能性が高くなります。) 異なるプログラムがテーブルのグループにアクセスする場合、各テーブルに同じ順序でアクセスすることに同意する必要があります。テーブルの場合は、可能な限り固定順序でテーブル内の行にアクセスします。これにより、デッドロックの可能性を大幅に減らすことができます。

    • 均等な条件を使用してデータにアクセスするようにしてください。これにより、

      同時挿入におけるギャップ ロックの影響を回避できます(実際には、等しいクエリではギャップ ロックも追加されます) 実際の必要性を超えるロック レベルを適用しないでください

    • 必要でない場合は、クエリ時に明示的なロックの使用を避けてください。 MVCC は、手動ロックを必要としない読み取りメカニズムを提供します。

    以上がMySQL のインテント共有ロック、インテント排他ロック、デッドロックとは何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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