ロック【Innodb分離の実現】
3898 ワード
グローバル・ロック、テーブル・レベル・ロックはServerレベルであり、ロー・レベル・ロックはストレージ・エンジン・レベルであり、Innodbのみがローおよびロックをサポートします.
グローバルロック:
データベース・インスタンス全体にロックをかけると、他のスレッドの次の文がブロックされます.データ更新文(データの削除)、データ定義文(テーブルの構築、テーブル構造の変更など)、クラス・トランザクションの更新のコミット文です.グローバルロックの典型的な使用シーンは、ライブラリ全体の論理バックアップを行うことです.
コマンド:Flush tables with read lock
開いているすべてのテーブルが閉じられ、すべてのデータベースのテーブルに対してunlock tablesが表示されるまでリードロックが追加されます.この操作は、データバックアップによく使用されます.つまり、すべての汚れたページをディスクにリフレッシュし、すべてのテーブルにリードロックをかけると、データファイルを直接コピーするのは安全です.
しかし、FTWRLを命令する場合、他の操作があり、時間のかかる操作ですか?まず書き込み操作といえば、このFTWRLは待たなければならないに違いない.書き込み操作が完了してからFTWRLを実行することができるのは理解できる.では、他の読み取り操作については?例えば、FLWRLが発行される前にquery:select count(*)from tbがある場合、FTWRLも待たなければならない(show processlistはwaiting for table flushを見ることができる).
テーブルロック:
MySQLにはテーブル・レベルのロックが2種類あります.1つはテーブル・ロック、1つはメタデータ・ロック(meta data lock,MDL).テーブルロックの構文はlock tables...read/writeです.FTWRLと同様に、unlock tablesでロックをアクティブに解除したり、クライアントが切断されたときに自動的に解放したりすることができます.lock tables構文は、他のスレッドの読み書きを制限するほか、本スレッドの次の操作オブジェクトも限定されることに注意してください.例えば、あるスレッドAでlock tables t 1 readが実行された場合、t 2 write;この文は、他のスレッドがt 1を書き、t 2を読み書きする文がブロックされます.また、スレッドAは、unlock tablesが実行されるまでは、t 1の読み書き、t 2の読み書きしか実行できない.書き込みt 1も許可されず、他のテーブルにもアクセスできないのは当然です.
表ロックの追加方法:MyISAMはクエリ文(SELECT)を実行する前に、関連するすべての表に自動的にリードロックを追加し、更新操作(UPDATE、DELETE、INSERTなど)を実行する前に、関連する表に自動的にライトロックを追加する.このプロセスはユーザーの介入を必要としないため、ユーザーは一般的にLOCK TABLEコマンドでMyISAM表に明示的にロックを追加する必要はない.
テーブルロックは1枚のテーブル全体にロックをかけ、リードロックとライトロックに分けることができますが、結局はテーブル全体をロックし、同時能力の低下を招き、ddl処理時に使用されるのが一般的です.
MyISAMのロックスケジューリング
MyISAMストレージエンジンのリード・ロックとライト・ロックは反発し,リード・ライト操作はシリアルである.では、あるプロセスはMyISAMテーブルのリードロックを要求し、別のプロセスも同じテーブルのライトロックを要求します.MySQLはどのように処理しますか?答えは
です.それだけでなく、リードリクエストがロック待ちキューに先着しても、ライトリクエストが後着しても、ライトロックはリードロックリクエストの前に挿入されます!これは、MySQLが読み取り要求よりも書き込み要求が一般的に重要だと考えているからです.これは、MyISAMテーブルが大量の更新操作とクエリー操作アプリケーションに適していない理由でもあります.大量の更新操作により、クエリー操作がリードロックを取得しにくくなり、永遠にブロックされる可能性があります.このような状況は時々非常に悪くなる可能性があります!幸いなことに、私たちはいくつかの設定でMyISAMのスケジューリング動作を調整することができます.起動パラメータ
low-priority-updates
を指定することにより、MyISAMエンジンはデフォルトでリード要求を優先する権利を付与する.コマンドSET LOW_PRIORITY_UPDATES=1
を実行することにより、その接続からの更新要求の優先度が低下する.INSERT
、UPDATE
、DELETE
文のLOW_PRIORITY
属性を指定することで、その文の優先度を下げます.MySQLは、システムパラメータ
max_write_lock_count
に適切な値を設定する折衷的な方法を提供し、テーブルのリードロックがこの値に達すると、MySQLは一時的にライトリクエストの優先度を低下させ、リードプロセスにロックの機会を与える.行ロック
MySQLの行ロックは、エンジン層で各エンジンが独自に実現しています.しかし、すべてのエンジンがロックをサポートしているわけではありません.例えば、MyISAMエンジンはロックをサポートしていません.ロー・ロックがサポートされていないということは、コンカレント・コントロールがテーブル・ロックのみを使用できることを意味します.このエンジンのテーブルでは、同じテーブル上でいつでも1つの更新しか実行できません.これは、ビジネス・コンカレントに影響します.InnoDBは行ロックをサポートしており、これもMyISAMがInnoDBに置き換えられる重要な原因の一つである.
今日は、主にInnoDBのロー・ロックについて説明し、ロックの競合を減らすことでビジネスの同時性を向上させる方法について説明します.行ロックはまた記録ロックになります.
単一のインデックス・レコードをロックします.ロックされているのはインデックス・レコードで、レコード自体ではありません.テーブルにインデックスがなくても、MySQLは自動的に暗黙的なrow_を作成します.idは集約インデックスとしてロックされる.
四、記録ロック
単一のインデックス・レコードにロックをかけます.ロックされているのは、レコード自体ではなくインデックス・レコードです.テーブルにインデックスがなくても、MySQLは自動的に暗黙的なrow_を作成します.idは集約インデックスとしてロックされる.
五、ギャップロック(gapロック)
レコード内の間隔をブラックアウトし、間隔内に他のトランザクションが挿入されないようにします.ギャップロックは主にRR独立性レベルに現れ、幻読を避ける.
一度にロックor 2段ロック?
大量の同時アクセスがあるため、デッドロックを予防するために、一般的なアプリケーションでは、メソッドの開始段階で、どのデータが使用されるかを事前に知っておき、すべてロックし、メソッドが実行された後、すべてロックを解除することを推奨しています.この方法は、トランザクションの開始段階でデータベースがどのデータを使用するか分からないため、ループデッドロックを効果的に回避できますが、データベースでは適用されません.
データベースは、トランザクションを2つのフェーズ、ロック・フェーズ、およびロック解除フェーズに分割する2つのロック・プロトコルに従っています(したがって、2つのロックと呼ばれます).