成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

MySQL 中的表級鎖很差勁嗎?

數據庫 MySQL
說到 MyISAM 和 InnoDB 的區別,很多人都知道,區別在于一個是表鎖一個是行鎖,那么小伙伴們有沒有想過,表鎖和行鎖有什么區別?各自又有哪些玩法?今天松哥就來和大家聊聊這個話題。

[[409831]]

當然不是!

其實本來今天是要和大家聊一聊 MyISAM 引擎的,結果在寫的過程中,又發現鎖這個話題可以單獨寫一篇,于是就有了今天的文章。

說到 MyISAM 和 InnoDB 的區別,很多人都知道,區別在于一個是表鎖一個是行鎖,那么小伙伴們有沒有想過,表鎖和行鎖有什么區別?各自又有哪些玩法?今天松哥就來和大家聊聊這個話題。

1.鎖

我們先來大致說一下 MySQL 中的鎖。

當多個事務或者多個進程訪問同一個資源的時候,為了保證數據的一致性,就需要用到 MySQL 鎖機制,從鎖定資源的角度來看,MySQL 中的鎖大致上可以分為三種:

  • 表級鎖(table-level locking):表級鎖的特點是開銷小,加鎖快,不會出現死鎖,但是鎖定粒度較大,發生鎖沖突的概率高,而且并發度也低。
  • 行級鎖(row-level locking):行級鎖的特點是開銷大,加鎖慢,有可能會出現死鎖,但是它的鎖定粒度小,發生鎖沖突的概率低,并發度也高。
  • 頁面鎖:開銷和加鎖時間界于表鎖和行鎖之間,會出現死鎖,鎖定粒度界于表鎖和行鎖之間,并發度一般。

雖然理論上有三種鎖,但是對于在坐的各位小伙伴包括松哥而言,我們日常開發接觸最多的還是前兩種,就是表級鎖和行級鎖。

在 MySQL 中,MyISAM 引擎是表級鎖,而 InnoDB 引擎則支持行級鎖,不過需要注意,其實 InnoDB 也支持表級鎖,只不過默認情況下是行級鎖。

2.表級鎖

MySQL 的表級鎖有兩種模式:

表共享讀鎖(Table Read Lock)。

表獨占寫鎖(Table Write Lock)。

MyISAM 引擎在執行 select 時會自動給相關表加讀鎖,在執行 update、delete 和 insert 時會自動給相關表加寫鎖。

2.1 表共享讀鎖

我們先來看表共享讀鎖,加了共享讀鎖的表,不會阻塞其他 session 的讀請求,但是會阻塞其他 session 的寫請求。

我們來演示一下這個效果。

在下面的案例中,我們會準備兩個窗口,代表兩個 session。

首先我們新建一張表,選擇 MyISAM 作為存儲引擎,DDL 如下:

  1. CREATE TABLE `user` ( 
  2.   `id` int(11) unsigned NOT NULL AUTO_INCREMENT, 
  3.   `namevarchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL
  4.   PRIMARY KEY (`id`) 
  5. ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; 

添加一條測試數據:

  1. insert into user(namevalues('javaboy'); 

然后我們在兩個命令行窗口分別登錄 mysql,模擬出兩個 session。

首先在第一個窗口為表添加讀鎖,如下:

  1. lock table user read

然后在第二個窗口去讀取數據:

  1. select * from user

可以發現,是可以正常讀取的。

然后我們嘗試在第二個窗口寫入一條數據:

  1. insert into user(namevalues('itboyhub'); 

這條寫入語句會 卡住,如下:

卡住的原因是因為 user 表目前被上了共享讀鎖,這個時候需要我們去到第一個窗口中,解除表的鎖定,這個時候第二個窗口中的這條插入 sql 就可以執行了。如下:

  1. unlock tables; 

當這條 SQL 完畢后,第二個窗口中的插入語句立馬就執行了。

如下是窗口2的截圖:

可以看到,加了共享讀鎖的表,不會阻塞其他 session 的讀(select)請求,但是會阻塞其他 session 的寫(insert、update、delete)請求。

需要注意的是,如果在同一條 SQL 中,同一個表名出線了 N 次,該表就要鎖定 N 次,如下:

思考:

我們在窗口 1 中給 user 表加了鎖,那么在窗口 1 中是否可以對 user 表執行 insert/update/delete 等寫操作呢?評論區 show 出你的答案~

2.2 表獨占寫鎖

這個獨占寫鎖就是大家鎖所熟知的排他鎖,它會阻塞其他進程對同一表的讀寫操作,只有當當前鎖釋放后,才會執行其他進程的讀寫操作。

我們來演示一下這個過程。

還是兩個窗口,首先我們我們在第一個窗口中執行鎖表操作:

  1. lock table user write; 

然后去第二個窗口中做查詢操作,如下:

可以看到,由于是排他鎖,所以查詢操作也被阻塞了。此時需要在窗口 1 中解除表的鎖定,窗口 2 中的查詢操作才會繼續執行下去。

這就是表獨占寫鎖,也就是排他鎖。

在 MyISAM 存儲引擎中,會自動為 SELECT 語句加上共享鎖,為 update/delete/insert 操作加上排他鎖。

2.3 concurrent_insert

前面我們講的是表級鎖的兩種基本模式,在具體的使用過程中,我們還可以通過 concurrent_insert 去配置一些并發行為。

concurrent_insert 有三種不同的取值:

NEVER:加了讀鎖之后,不允許其他 session 并發插入。

AUTO:加了讀鎖之后,如果表里沒有刪除過數據,其他 session 就可以并發插入。

ALWAYS:加了讀鎖之后,允許其他 session 并發插入。

需要注意的是,在 MySQL5.5.3 之前,NEVER、AUTO 以及 ALWAYS 分別使用 0、1、2 代替。

通過 show global variables like '%concurrent_insert%' 命令我們可以查看當前數據庫中 concurrent_insert 的取值,如下:

可以看到,數據庫中默認的 concurrent_insert 取值為 AUTO。有小伙伴可能會說,啥?AUTO?那為啥我在 2.1 小結中,當表加了讀鎖之后,其他 session 無法插入數據呢?這其實跟加鎖方式有關,我們一起來看下。

還是兩個窗口,首先我們在第一個窗口中為表添加讀鎖,如下:

  1. lock table user read local

可以看到,最后多了一個 local,這就是關鍵。

接下來我們在窗口 2 中去嘗試讀寫操作,如下:

從圖中可以看到,讀寫操作都可以順利執行。

但是這個時候,如果我們去窗口 1 中執行查詢,如下:

可以看到,這里并看不到窗口 2 中剛剛添加的那條數據,換句話說,窗口 2 中添加的數據對窗口 1 是不可以見的,必須等窗口 1 中的鎖釋放之后,才可以看到窗口 2 中添加的數據。

如下圖,釋放鎖之后,就可以看到另外一個窗口添加進來的數據了:

這是我給大家演示的默認的 concurrent_insert 的行為,大家也可以通過如下 SQL 修改該值:

  1. set global concurrent_insert = ALWAYS; 

2.4 鎖的優先級

在 MyISAM 中,默認情況下,寫鎖的優先級要高,不過開發者也可以自行調整這個默認鎖的優先級。

話說回來,由于 MyISAM 是表鎖,所以不建議用在需要頻繁更新的場景下,否則可能會造成長時間的鎖等待。所以下面的優先級調整,僅僅作為技術層面的探討。

修改 SQL 優先級

首先我們可以在執行 SQL 的時候,順便修改其優先級:

例如執行 select 的時候可以使用 HIGH_PRIORITY 來提高該語句的優先級,如下:

在執行 delete/update/insert 等操作的時候,可以使用 LOW_PRIORITY 來降低其優先級,以便讓讀取操作先執行:

當然我們也可以通過如下 SQL 讓所有支持 LOW_PRIORITY 選項的語句都默認地按照低優先級來處理。

  1. set LOW_PRIORITY_UPDATES = 1 

修改寫鎖上限

我們可以修改 MAX_WRITE_LOCK_COUNT 的值,該變量默認值如下圖:

這個值表示當一個表的寫鎖數量達到給定的值后,就降低寫鎖的優先級,讓讀鎖有機會執行。如果有需要,我們可以自行調整這個值,調整方式如下:

  1. set GLOBAL MAX_WRITE_LOCK_COUNT=1024; 

3.行級鎖

行級鎖松哥留到講 InnoDB 的時候再和大家聊,今天我們就先扯這么多~

參考資料:

1.https://database.51cto.com/art/201910/604421.htm

2.https://zhuanlan.zhihu.com/p/123962424

本文轉載自微信公眾號「江南一點雨」,可以通過以下二維碼關注。轉載本文請聯系江南一點雨公眾號。

 

責任編輯:武曉燕 來源: 江南一點雨
相關推薦

2020-02-06 10:02:45

MySQL數據庫全局鎖

2010-05-24 12:50:59

MySQL表級鎖

2024-11-29 07:38:12

MySQL數據庫

2022-10-24 00:33:59

MySQL全局鎖行級鎖

2025-02-10 09:58:48

2021-11-26 08:07:16

MySQL SQL 語句數據庫

2025-02-14 10:03:40

2024-03-04 00:01:00

鎖表鎖行MySQL

2023-12-26 08:17:04

Go框架Go 語言

2024-05-13 12:44:00

InnodbMySQL行級鎖

2010-11-22 14:27:05

MySQL鎖表

2020-04-28 08:55:11

MySQL數據庫

2010-11-22 14:42:13

MySQL行級鎖

2010-10-15 14:10:56

Mysql行級鎖

2010-05-24 12:26:26

MySQL鎖表

2018-07-31 10:10:06

MySQLInnoDB死鎖

2013-03-20 18:14:35

架構架構設計項目

2024-06-20 08:03:35

MySQL數據表版本

2020-10-20 13:50:47

MySQL數據庫

2010-01-21 17:14:40

C++兼容
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 欧美在线一区二区三区 | 中国一级特黄毛片大片 | 中文字幕成人av | 欧美日韩中文在线 | 亚洲国产aⅴ精品 | av毛片免费 | 热99| 久久久精品一区二区三区四季av | 午夜爱爱毛片xxxx视频免费看 | 日韩午夜| 国色天香综合网 | 久久国产精品99久久久久久丝袜 | 国产日韩欧美精品一区二区三区 | xxx.在线观看 | 亚洲日本一区二区三区四区 | 国产精品国产成人国产三级 | 久久骚 | 五月激情婷婷网 | 免费一区二区三区 | 久久精品手机视频 | 久久se精品一区精品二区 | 欧美性区 | 日本三级线观看 视频 | 999视频在线播放 | 欧美精品一区二区三区蜜臀 | 日韩一二区 | 欧美日韩一二区 | 国产精品亚洲一区 | 97精品国产97久久久久久免费 | 欧美一级久久 | 成人影院免费视频 | 久久久久久高清 | 中文字幕免费中文 | 亚洲精品一区在线观看 | 一级a爱片性色毛片免费 | 成年免费大片黄在线观看岛国 | 国产精品 亚洲一区 | 日韩精品三区 | 欧美精品一区二区三区四区 在线 | 欧美成人不卡 | 久久久久久成人 |