この記事では、MySQL データベースのロック メカニズムについて説明します。必要な方は参考にしていただければ幸いです。
同時実行制御
ロック
同時トランザクションが同時にリソースにアクセスすると、データの不整合が生じる可能性があるため、データベース データの一貫性を確保するためにデータ アクセスを順序付けるメカニズムが必要です。ロックはメカニズムの 1 つです (推奨チュートリアル:
MySQL チュートリアル )
ロックの分類
行レベル ロック
行レベルのロックは Mysql で最も詳細なロックであり、現在操作されている行のみがロックされることを意味します。行レベルのロックにより、データベース操作における競合を大幅に減らすことができます。ロックの粒度は最も小さくなりますが、ロックのオーバーヘッドも最大になります。行レベルのロックは - 共有ロック
と 排他ロック
特徴: オーバーヘッドが高く、ロックの粒度が遅い。ロック競合の可能性が最も小さく、最も低い同時実行性が最も高い テーブル レベルのロック
ページ レベル ロックは Mysql のロックの一種で、そのロック粒度は行レベル ロックとテーブル レベル ロックの間です。テーブルレベルのロックは高速ですが、競合が多くなります。行レベルのロックは競合がほとんどありませんが、低速です。ページレベルのロックは、隣接するレコードのグループをロックするために使用されます。 BDB はページ レベルのロックをサポートします Mysql 共通ストレージ エンジンのロック メカニズム
MyISAM と MEMORY はテーブル レベルのロックを使用します
BDB はページ レベルのロックまたはテーブル レベルのロックを使用します。デフォルトはページ レベルのロックです。 InnoDB は行レベルのロックとテーブル レベルのロックをサポートします。デフォルトは行レベルのロックです-
InnoDB の行ロックとテーブル ロック
InnoDB エンジンは行ロックとテーブル ロックの両方をサポートしています。そのため、テーブル全体がロックされるのはいつかということです。 、行がロックされるのはいつですか? ?
InnoDB の行ロックは、インデックス上のインデックス エントリをロックすることによって実現されます。これは、データ ブロック内の対応するデータ行をロックする Mysql や Oracle とは異なります。 InnoDB のこの行ロック実装機能は次のことを意味します: - インデックス条件を通じてデータが取得される場合にのみ、InnoDB は行レベルのロックを使用します。それ以外の場合、InnoDb はテーブル ロックを使用します
実用的アプリケーションを使用する場合は、InnoDB 行ロックのこの機能に注意する必要があります。そうしないと、大量のロック競合が発生しやすくなり、同時実行パフォーマンスに影響を及ぼします。 InnoDB が使用するインデックス条件 これは行ロックではなくテーブル ロックです MySQL の行ロックはレコードのロックではなくインデックスのロックであるため、異なる行のレコードは同じインデックスのキーを使用するとロックの競合が発生する場合にアクセスされます。
-
テーブルに複数のインデックスがある場合、InnoDB では、主キー インデックス、一意インデックス、通常のインデックスのいずれが使用されているかに関係なく、異なるトランザクションが異なるインデックスを使用して異なる行をロックできます。 Row lock を使用してデータをロックします。
-
インデックス フィールドが条件で使用されている場合でも、データの取得にインデックスを使用するかどうかは、さまざまなコストを判断して MySQL によって決定されます。行プラン。一部の非常に小さなテーブルなど、MySQL がテーブル全体のスキャンの方が効率的であると判断する場合、InnoDB は行ロックの代わりにテーブル ロックを使用します。したがって、ロックの競合を分析するときは、SQL 実行計画を確認することを忘れないでください
行レベルのロックとデッドロック
MyISAM は常に必要なものをすべて一度に取得するため、MyISAM はデッドロックを生成しません。 ロック、またはすべてが満たされている場合または全員が待っています。 InnoDB では、ロックは段階的に取得されるため、デッドロックが発生する可能性があります。
MySQL では、行レベルのロックはレコードを直接ロックするのではなく、インデックスをロックします。インデックスは主キー インデックスと非主キー インデックスに分けられます。SQL ステートメントが主キー インデックスで動作する場合、MySQL はまず主キー インデックスをロックします。次に、関連する主キー インデックスをロックします。更新および削除操作中に、MySQL は where 条件によってスキャンされたすべてのインデックス レコードをロックするだけでなく、隣接するキー値もロックします。これは、いわゆるネクスト キー ロックです。
デッドロック: 2 つのトランザクションが同時に実行されると、1 つは主キー インデックスをロックし、他の関連するインデックスを待機します。もう 1 つは、非主キー インデックスをロックし、主キー インデックスを待機しています。デッドロックが発生します。
- #デッドロックが発生すると、通常、InnoDB はそれを検出し、1 つのトランザクションにロックを解放してロールバックさせ、別のトランザクションにロックを取得させてトランザクションを完了させることができます
デッドロックの回避
#
異なるプログラムが複数のテーブルに同時にアクセスする場合は、同じ順序でテーブルにアクセスすることに同意するようにしてください。そうすることで、デッドロックの可能性を大幅に減らすことができます 同じトランザクション内で、デッドロックの可能性を減らすために必要なすべてのリソースを一度にロックするようにしてください。 デッドロックが発生しやすいビジネス部分の場合は、アップグレードされたロック粒度を使用して、テーブル レベルのロックを通じてデッドロックを軽減してみてください。 共有ロックと排他的ロック
行レベルのロックは次のとおりです。 MySQL では、最も細かいロック粒度である行レベルのロックにより、データベース操作の競合を大幅に軽減できます。行レベルのロックは、共有ロックと排他的ロックに分けられます。 1. 共有ロック
使用法:
SELECT ... FOR UPDATE
。クエリ ステートメントの後に - FOR UPDATE
を追加すると、MySQL はクエリ結果の各行に排他ロックを追加します。他のスレッドがクエリ結果セットの行に対して排他ロックを使用しない場合、排他ロックが適用されます。それ以外の場合はブロックされます。
3. インテンション ロックインテンション ロックはテーブル レベルのロックです。トランザクションで次のことを明らかにします。 行に対して要求されるロックのタイプ。 InnoDB の 2 つのテーブル ロック:
意図共有ロック (IS): トランザクションがデータ行に共有ロックを追加する準備をしていることを示します。共有ロックがデータ行に追加されます。 テーブルの IS ロックは、事前に取得する必要があります。
-
意図的排他ロック (IX): トランザクションがデータ行に排他ロックを追加する準備をしていることを示します。データ行。トランザクションが最初にデータ行に排他ロックを追加する必要があることを示します。テーブルの IX ロックが削除されます。
-
インテンション ロックは、InnoDB によって自動的に追加され、ユーザーの介入は必要ありません
-
概要
- 挿入、更新、削除の場合、InnoDB は関連するデータに排他ロックを自動的に追加します。 Select ステートメント。InnoDB はロックを追加せず、トランザクションは次のステートメントを通じて明示的に追加できます。 共有ロックまたは排他的ロック
共有ロック: select ... LOCK IN SHARE MODE
排他ロック: SELECT ... FOR UPDATE
以上がmysqlデータベースロックメカニズムの概要の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。