10bet网址
MySQL 5.6リファレンスマニュアル
本手册下载
PDF (Ltr)- 26.8 mb
PDF (A4)- 26.8 mb


14.2.3 InnoDBのロックモド

InnoDBでは,2のロックタ(共有 (年代)ロック排他 (X)ロックがある標準の行レベルロックが実装されます。レコド,ギャップ,およびネクストキ,セクション14.2.6 " InnoDBのレコド,ギャップ,およびネクストキロック"を参照してください。

  • 共有 (年代)ロックでは,ロックを保持するトランザクションによる行の読み取りが許可されます。

  • 排他 (X)ロックでは,ロックを保持するトランザクションによる行の更新または削除が許可されます。

トランザクションT1が行rに対する共有(年代)ロックを保持している場合,別のトランザクションT2からの行rに対するロック要求は次のように処理されます。

  • T2による年代ロックに対するリクエストは,すぐに付与できます。結果として,T1T2の両方がr上で年代ロックを保持します。

  • T2によるXロックに対するリクエストは,すぐに付与できません。

トランザクションT1が行r上で排他(X)ロックを保持している場合は,r上のいずれかのタ邮箱プのロックに対する一部の個別のトランザクションT2からのリクエストは,すぐに付与できません。代わりに,トランザクションT2は,行r上でトランザクションT1のロックが解放されるまで待機する必要があります。

ンテンションロック

さらに,InnoDBでは,レコドロックとテブル全体のロックが共存することを許可する複数粒度ロックもサポトされています。複数粒度レベルでのロックを実用的にするために,ンテンションロックと呼ばれる追加のロックタ邮箱プが使用されます。ンテンションロックとは、あとでトランザクションがそのテーブル内の行で必要となるロックのタイプ (共有または排他) を示すInnoDBのテブルロックです。トランザクションTがテブルt上に指定されたタプのロックをリクエストしたと仮定すると,InnoDBで使用されるereplicationンテンションロックには,次の2 ereplicationタereplicationプがあります。

  • ンテンション共有):トランザクションTは意図的に,テブルt内の各行に年代ロックを設定します。

  • ンテンション排他9):トランザクションTは意図的に,これらの行にXロックを設定します。

たとえば,选择……共享模式锁定ロックを設定し,选择……更新9ロックを設定します。

ンテンションロックの手順は次のとおりです。

  • トランザクションがテブルtのある行の年代ロックを取得するには,まずtまたはそれより強いロックを取得する必要があります。

  • トランザクションがある行のXロックを取得するには,まずt9ロックを取得する必要があります。

これらのルルをまとめる際は,次に示すロックタ邮箱プ互換性マトリクスを使用すると便利です。

X 9 年代
X 競合 競合 競合 競合
9 競合 互換 競合 互換
年代 競合 競合 互換 互換
競合 互換 互換 互換

ロックに既存のロックとの互換性がある場合は,リクエスト元のトランザクションにロックが付与されますが,既存のロックと競合している場合は,ロックが付与されません。トランザクションは,競合している既存のロックが解放されるまで待機します。ロックリクエストが既存のロックと競合し,デッドロックが発生するために付与できない場合は,エラが発生します。

したがって,ンテンションロックでは,完全なテ,ブルリクエスト(锁表……写など)以外は何もブロックされません。9およびロックの主な目的は,だれかが行をロックしていることや,テーブル内の行をロックしようとしていることを示すことです。

デッドロックの例

次の例は,ロックリクエストによってデッドロックが発生したときに,どのようにエラーが発生するのかを示しています。aとbの2。

最初に,クラ1。トランザクション内で,一个は共有モドで選択した行で年代ロックを取得します。

CREATE TABLE t (i INT) = InnoDB;查询OK, 0行影响(1.07秒)mysql> INSERT INTO t (i) VALUES(1);查询OK, 1 row affected (0.09 sec) mysql> START TRANSACTION;查询OK, 0 rows affected (0.00 sec) mysql> SELECT * FROM WHERE i = 1 LOCK IN SHARE MODE;+------+ | 我  | +------+ | 1  | +------+ 1行集(0.10秒)

次に,クラe eアントbがトランザクションを開始し,テe eブルから行を削除しようとします。

mysql >开始交易;查询OK, 0 rows affected (0.00 sec) mysql> DELETE FROM t WHERE i = 1;

削除操作を行うには,Xロックが必要です。クラアントaが保持している年代ロックとの互換性がないために,ロックを付与できません。そのため,リクエストはその行のロックリクエストのキューに入れられ,クライアントBはブロックされます。

最後に,クラe .アントaもテe .ブルから行を削除しようとします。

删除t WHERE i = 1;错误1213(40001):当试图获得锁时发现死锁;试着重新启动事务

クラアントaは行を削除するためにXロックが必要であるため,ここでデッドロックが発生します。ただし,クラeアントbはすでにXロックに対するリクエストを持っていて,クラeアントaがその年代ロックを解放するまで待機しているため,そのロックリクエストを付与することはできません。BによるXロックに対する以前のリクエストが原因で,一个が保持している年代ロックをXロックにアップグレドすることもできません。その結果,InnoDBはクラアントのいずれかに対してエラを生成し,そのロックを解放します。クラアントは,次のエラを返します。

错误1213(40001):当试图获得锁时发现死锁;试着重新启动事务

この時点で,ほかのクライアントに対するロックリクエストを付与できるようになり,テーブルから行が削除されます。

注記

InnoDB Monitorの出力の最新检测到死锁セクションには,在锁表等待图中搜索过深或过长,将回滚后续事务というメッセジが含まれます。これは,待機リスト上のトランザクション数が200の制限に達したことを示します。この制限は,LOCK_MAX_DEPTH_IN_DEADLOCK_CHECKで定義されます。200年個のトランザクションを超える待機リストはデッドロックとして処理され,待機リストをチェックしようとするトランザクションはロールバックされます。

ロックスレッドが待機リスト上のトランザクションが所有する1000000個を超えるロックを参照する必要がある場合も,同じエラーが発生する可能性があります。1,000,000個のロック制限は,LOCK_MAX_N_STEPS_IN_DEADLOCK_CHECKで定義されます。


本手册下载
PDF (Ltr)- 26.8 mb
PDF (A4)- 26.8 mb