準備オーケー
テーブルtb_innodb_lockを作成します
test_innodb_lockが存在する場合はテーブルを削除します。 CREATE TABLE test_innodb_lock( INT(11)、 b VARCHAR(20) )ENGINE INNODB DEFAULT charset = utf8; test_innodb_lock値(1、 'a');に挿入します。 test_innodb_lock値(2、 'b');に挿入します。 test_innodb_lock値(3、 'c');に挿入します。 test_innodb_lock値(4、 'd');に挿入します。 test_innodb_lock値(5、 'e');に挿入します。
インデックスを作成する
test_innodb_lock(a);にインデックスidx_lock_aを作成します。 test_innodb_lock(b);にインデックスidx_lock_bを作成します。
MySQLロックデモ
まず、自動コミットトランザクションを手動コミットに変更します。
set autocommit=0;
2つのセッションウィンドウAとBを開始し、一方がロックを取得し、もう一方が取得せずにブロックされることをシミュレートします。
行ロック(書き込みと読み取り)
ウィンドウの実行
test_innodb_lock set b = 'a1'を更新します。ここでa = 1;
SELECT * from test_innodb_lock;
更新された結果をウィンドウAで確認できます
Bウィンドウの実行
SELECT * from test_innodb_lock;
Bウィンドウでは更新された結果を確認できませんが、古いデータは引き続き表示されます。これは、Aウィンドウで実行されたSQLステートメントによってa = 1のレコードがロックされ、コミット操作が実行されなかったためです。したがって、ウィンドウBには引き続き古いデータが表示されます。これは、MySQL分離レベルでの「読み取りコミット」です。
ウィンドウAはコミット操作を実行します
コミット;
ウィンドウBクエリ
SELECT * from test_innodb_lock;
この時点で、ウィンドウBが最新のデータを読み取ったことがわかりました。
行ロック(書き込みと書き込み)
ウィンドウAはa = 1レコードの更新を実行します
test_innodb_lock set b = 'a2'を更新します。ここでa = 1;
このとき、コミットはなく、ウィンドウAによってロックが保持されます。
ウィンドウBは、a = 1のレコードも更新します
test_innodb_lock set b = 'a3'を更新します。ここでa = 1;
ご覧のとおり、ウィンドウAはまだコミットを実行しておらず、ロックを保持しているため、ウィンドウBはブロックされています。ウィンドウBは、行a = 1に記録されているロックを取得できないため、待機がブロックされています。
ウィンドウAはコミット操作を実行します
コミット;
ウィンドウBの変更
この時点でウィンドウBが正常に実行されていることがわかります。
テーブルロック
インデックスに障害が発生すると、行ロックがテーブルロックにアップグレードされます。インデックス障害の方法の1つは、インデックスを自動または手動で変更することです。フィールド自体は整数です。引用符を追加すると、文字列になります。今回はインデックスが無効になります。
ウィンドウAはa = 1のレコードを更新します
test_innodb_lock set b = 'a4'を更新します。ここでa = 1またはa = 2;
ウィンドウBはa = 2のレコードを更新します
test_innodb_lock set b = 'b1'を更新します。ここでa = 3;
このとき、ウィンドウAとウィンドウBの更新された行が異なっていても、ウィンドウAのインデックスが失敗したため、ウィンドウBがブロックされたままであることが発見されました。これにより、行ロックがテーブルロックにアップグレードされ、テーブル全体とインデックスウィンドウがロックされました。 Bはブロックされています。
ウィンドウAはコミット操作を実行します
コミット;
ウィンドウBの変更
この時点でウィンドウBが正常に実行されていることがわかります。
ギャップロック
ギャップロックとは
範囲条件を使用してデータを照会すると、InnoDBはこの範囲のデータをロックします。たとえば、IDが1、3、5、7の4つのデータがあり、1〜7の範囲のデータを検索します。その後、1〜7がロックされます。2、4、および6も1〜7の範囲ですが、これらのデータレコードは存在せず、これらの2、4、および6はギャップと呼ばれます。
ギャップロックの害
範囲を検索すると、範囲全体のすべてのデータがロックされます。この範囲に存在しないデータも無害にロックされます。たとえば、1、3、5、7に2を挿入したいのですが、今回は1 -7はロックされており、2はまったく挿入できません。一部のシナリオでは、パフォーマンスに大きな影響を与えます
ギャップロックデモ
まず、フィールドaの値を1、3、5、7、9に変更します。
ウィンドウAは、a = 1〜7の範囲でデータを更新します
test_innodb_lock set b = 'b5'を更新します。ここでa> 1およびa <7;
ウィンドウBはa = 2にデータを挿入します
test_innodb_lockに挿入values(2、 "b6");
このとき、1〜7の範囲のデータがギャップでロックされてロックされているため、ウィンドウBでa = 2を更新する操作が待機していることがわかります。ウィンドウAがcommitを実行した場合にのみ、ウィンドウBのa = 2で更新を成功させることができます。
行ロック分析
SQL分析コマンドを実行する
'innodb_row_lock%'のようなステータスを表示します。
Variable_nameの説明
Innodb_row_lock_current_waits:現在待機しているロックの数。
Innodb_row_lock_time:システムの起動から現在のロックまでの時間。
Innodb_row_lock_time_avg:毎回ロックを待機するために費やされた平均時間。
Innodb_row_lock_time_max:システムが起動してからロックが待機するのにかかる最長時間。
Innodb_row_lock_waits:システムが起動してから現在までにロックを待機した合計数。
やっと
ここを見てくれてありがとう、記事には欠陥があります、指摘することを歓迎します;それがうまく書かれていると思うなら、私に親指を上げてください。