中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何理解MySQL行鎖、表鎖、間隙鎖

發布時間:2021-10-22 15:51:05 來源:億速云 閱讀:179 作者:iii 欄目:數據庫

本篇內容介紹了“如何理解MySQL行鎖、表鎖、間隙鎖”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

準備工作

創建表 tb_innodb_lock

drop table if exists test_innodb_lock;  CREATE TABLE test_innodb_lock (      a INT (11),      b VARCHAR (20)  ) ENGINE INNODB DEFAULT charset = utf8;  insert into test_innodb_lock values (1,'a');  insert into test_innodb_lock values (2,'b');  insert into test_innodb_lock values (3,'c');  insert into test_innodb_lock values (4,'d');  insert into test_innodb_lock values (5,'e');

創建索引

create index idx_lock_a on test_innodb_lock(a);  create index idx_lock_b on test_innodb_lock(b);

MySQL 各種鎖演示

  •  先將自動提交事務改成手動提交:set autocommit=0;

  •  我們啟動兩個會話窗口 A 和 B,模擬一個搶到鎖,一個沒搶到被阻塞住了。

行鎖(寫&讀)

  • A 窗口執行 

update test_innodb_lock set b='a1' where a=1;
SELECT * from test_innodb_lock;

如何理解MySQL行鎖、表鎖、間隙鎖

我們可以看到 A 窗口可以看到更新后的結果

  •  B 窗口執行 

SELECT * from test_innodb_lock;

如何理解MySQL行鎖、表鎖、間隙鎖

我們可以看到 B 窗口不能看到更新后的結果,看到的還是老數據,這是因為 a = 1 的這行記錄被 A 窗口執行的 SQL 語句搶到了鎖,并且沒有執行 commit 提交操作。所以窗口 B 看到的還是老數據。這就是 MySQL 隔離級別中的"讀已提交"。

  •  窗口 A 執行 commit 操作 

COMMIT;
  •  窗口 B 查詢 

SELECT * from test_innodb_lock;

如何理解MySQL行鎖、表鎖、間隙鎖

這個時候我們發現窗口 B 已經讀取到最新數據了

行鎖(寫&寫)

  •  窗口 A 執行更新 a = 1 的記錄 

update test_innodb_lock set b='a2' where a=1;

這時候并沒有 commit 提交,鎖是窗口 A 持有。

  •  窗口 B 也執行更新 a = 1 的記錄 

update test_innodb_lock set b='a3' where a=1;

如何理解MySQL行鎖、表鎖、間隙鎖

可以看到,窗口 B 一直處于阻塞狀態,因為窗口 A 還沒有執行 commit,還持有鎖。窗口 B 搶不到 a = 1 這行記錄的鎖,所以一直阻塞等待。

  •  窗口 A 執行 commit 操作 

COMMIT;

  窗口 B 的變化

如何理解MySQL行鎖、表鎖、間隙鎖

可以看到這個時候窗口 B 已經執行成功了

表鎖

當索引失效的時候,行鎖會升級成表鎖,索引失效的其中一個方法是對索引自動 or 手動的換型。a 字段本身是 integer,我們加上引號,就變成了 String,這個時候索引就會失效了。

  •  窗口 A 更新 a = 1 的記錄 

update test_innodb_lock set b='a4' where a=1 or a=2;
  •  窗口 B 更新 a = 2 的記錄 

update test_innodb_lock set b='b1' where a=3;

如何理解MySQL行鎖、表鎖、間隙鎖

這個時候發現,雖然窗口 A 和 B 更新的行不一樣,但是窗口 B 還是被阻塞住了,就是因為窗口 A 的索引失效,導致行鎖升級成了表鎖,把整個表鎖住了,索引窗口 B 被阻塞了。

  •  窗口 A 執行 commit 操作 

COMMIT;
  •  窗口 B 的變化

如何理解MySQL行鎖、表鎖、間隙鎖

可以看到這個時候窗口 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 范圍的數據 

update test_innodb_lock set b='b5' where a>1 and a<7;
  •  窗口 B 在 a = 2 的位置插入數據 

insert into test_innodb_lock values(2, "b6");

如何理解MySQL行鎖、表鎖、間隙鎖

這個時候發現窗口 B 更新 a = 2 的操作一直在等待,因為 1~7 范圍的數據被間隙鎖,鎖住了。只有等窗口 A 執行 commit,窗口 B 的 a = 2 才能更新成功

行鎖分析

  •  執行 SQL 分析命令 

show status like 'innodb_row_lock%';

如何理解MySQL行鎖、表鎖、間隙鎖

  •  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:系統啟動后到現在總共等待鎖的次數。

“如何理解MySQL行鎖、表鎖、間隙鎖”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

海城市| 海南省| 来凤县| 江津市| 新晃| 贵溪市| 泰顺县| 中卫市| 娄底市| 皋兰县| 阳东县| 滦南县| 嘉兴市| 彭山县| 米泉市| 桦南县| 许昌市| 三亚市| 府谷县| 昌平区| 钟祥市| 韶关市| 扶余县| 县级市| 徐州市| 金门县| 襄汾县| 梨树县| 辽宁省| 怀宁县| 昌图县| 富阳市| 页游| 泸定县| 郸城县| 芜湖县| 尉犁县| 宜昌市| 苗栗市| 淮南市| 团风县|