1つ、共有ロック、排他ロック
- InnoDBは、次の2つの標準行レベルロックを実装します。
- 共有ロック(Sロック):トランザクションがデータの行を読み取ることができるようにします
- 排他的ロック(Xロック):トランザクションがデータの行を削除または更新できるようにします
ロック間の互換性
トランザクションが行rの共有ロックを占有している場合:その後、他のトランザクションはすぐに共有ロックを獲得することができますが、一部のトランザクションが排他ロックを取得したい場合、彼らがリリースされる行r上のすべての共有ロックを待って待機する必要があります。
トランザクションが行rの排他ロックを占有している場合:変更の共有ロックを占有しているか排他ロックを占有しているかに関係なく、他のトランザクションは待機する必要があります
次の図は、共有ロックと排他ロックの互換性を示しています。
第二に、意図ロック
- さらに、InnoDBストレージエンジンはマルチグラニュラリティロックをサポートします。これにより、行レベルでのトランザクションロックとテーブルレベルのロックを同時に存在させることができます。さまざまな強度でのロック操作をサポートするために、InnoDBストレージエンジンは、インテンションロックと呼ばれる追加のロック方法をサポートしています。
- InnoDBは、比較的単純なインテンションロックの設計をサポートしており、そのインテンションロックはテーブルレベルのロックです。設計の目的は、主に、トランザクションの次の行で要求されるロックのタイプを明らかにすることです。
- 2つのインテントロックをサポートします。
- 意図的な共有ロック(ISロック):トランザクションがテーブルの特定の行で共有ロックを取得しようとしています
- インテント排他ロック(IXロック):トランザクションがテーブルの特定の行で排他ロックを取得しようとしています
原理図
- 意図的なロックは、ロックされたオブジェクトを複数のレベルに分割します。意図的なロックは、トランザクションがよりきめ細かいレベルでロックすることを望んでいることを意味します。以下に示すように
- ロックされたオブジェクトをツリーとして扱い、次に最下位レベルのオブジェクトをロックし(つまり、最も細かいオブジェクトをロックし)、最初に粗いオブジェクトをロックします。
- たとえば、ページ上のレコードの行をXロックでロックする必要がある場合は、データベース、テーブル、およびページの意図をロックし、最後にXでレコードをロックする必要があります。その一部が待機を引き起こす場合、操作は粗粒度ロックの完了を待機する必要があります。
- 例:トランザクションがすでにテーブルに対してSテーブルロックを実行しており、この時点でレコードにXロックを追加する必要があります。この時点で、テーブルにIXロックを追加する必要がありますが、テーブルにはSロックがあるため、テーブルロック操作の完了を待つ必要があります
3、ロック情報を表示します
ロック要求情報を表示する
- 次の情報から、現在のロック要求情報を表示できます。
show engine innodb status\G
- SQLステートメント「select * from t where a <4 lock insharemode」が待機していることがわかります。
- RECORDLOCKSスペースID30ページ番号3nビット72テーブル「test」のインデックス「PRIMARY」。「t」trxid 48B89BD lock_mode Xはrecをロックしますが、ギャップはロックされたリソースを示します
- ギャップではなくrecをロックするということは、ロックが範囲ではなくインデックスであることを意味します
- InnoDB 1.0バージョンより前では、ユーザーはコマンドSHOW FULL PROCESSLIST、SHOW ENGINE INNODB STATUSを介してのみ現在のデータベースのロック要求を表示し、トランザクションロックの状況を判断できます。
- InnoDBバージョン1.0は最初から、データベースinformation_schemaにテーブルinnodb_trx、innodb_locks、innodb_lock_waitsを追加します。これらの3つのテーブルを使用すると、現在のトランザクションを監視し、発生する可能性のあるロックの問題を分析するのが簡単になります。
innodb_trxテーブル
- このテーブルは、次の8つのフィールドで構成されています。
- 具体的な例を見てみましょう。
- trx_state列で、trx_idが730FEEのトランザクションが現在実行中であり、trx_idが7311F4のトランザクションが現在「LOCKWAIT」状態であり、実行中のSQLステートメントがtrx_queryに表示されていることを確認します。
- innodb_trxテーブルは、現在実行中のInnoDBトランザクションを示し、直接ロック条件の一部を決定することができません
innodb_locks表
- あなたがロックを表示する必要がある場合、あなたはまたinnodb_locksテーブルにアクセスする必要があります。表のフィールドは次のとおりです。
- 特定の例を見てみましょう:
- rx_idが730FEEのトランザクションは、Xの行ロックをテーブルの親に追加し、trx_idが7311F4のトランザクションは、Sの行ロックをテーブルの親に追加します。
- どちらも同じ行レコードをロックし、行レコードの主キー値は1であるため、lock_dataは1であり、同じリソースが適用されるため、待機します。
- lock_dataの値に関する注意: lock_dataの値は「信頼できる」値ではありません。たとえば、ユーザーが範囲検索を実行すると、lock_dataは最初の行の主キー値のみを返す場合があります。現在のリソースがロックされている場合、同時に、ロックされたページがあればフラッシュさ起因InnoDBストレージエンジンのバッファプールの容量に、バッファー・プールから、値がNULLとして表示されるinnodb_locks表を表示するとき。、即ちつまり、InnoDBはディスクから再度検索しません
innodb_lock_wait表
- ユーザーは、テーブルinnodb_locksを介して各テーブルのロック状態を確認した後、これによって引き起こされる待機状況を判断できます。トランザクションが小さい場合は直感的に確認できますが、トランザクション量が多い場合はロックや待機が多く、現時点での判断は容易ではありません。ただし、innnodb_lock_waitsテーブルは、現在のトランザクションの待機を反映できます。
- このテーブルは、次の意味を持つ4つのフィールドで構成されています。
- 具体的な例を見てみましょう。
- この例では、どのトランザクションが別のトランザクションをブロックしているかを確認できます
- もちろん、ここではトランザクションIDとロックIDのみを示します。より詳細な情報を観察したい場合は、次の共同クエリを実行できます