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

什么是MySQL鎖?有哪些鎖類型?

開發 前端
很多人都一樣,在剛開始學習MySQL中鎖的時候,網上一查出來一堆,什么表鎖、行鎖、讀鎖、寫鎖、悲觀鎖、樂觀鎖等等等,直接整個人就懵了。

為什么需要引入鎖

鎖是計算機協調多個進程或線程并發訪問某一資源的一種機制,在并發事務下保證數據的正確和唯一性。

圖片圖片

鎖在 MySQL 中是非常重要的一部分,對 MySQL 的數據訪問并發有著舉足輕重的影響

MySQL中的鎖是在服務器層或存儲引擎層實現的,不同的存儲引擎的鎖機制也有較大的區別。

MySQL鎖的實現

很多人都一樣,在剛開始學習MySQL中鎖的時候,網上一查出來一堆,什么表鎖、行鎖、讀鎖、寫鎖、悲觀鎖、樂觀鎖等等等,直接整個人就懵了。

本文我們將以鎖粒度的角度去看MySQL鎖的分類情況

沒事,先看看小許歸納的鎖知識大綱,先對鎖的位置和鎖歸屬的存儲引擎有個前置了解!

圖片圖片

全局鎖

全局鎖就是對整個數據庫實例加鎖,MySQL有個全局讀鎖的命令如下:

flush tables with read lock(FTWRL)

執行后,整個數據庫就處于只讀狀態(不能寫入) 了,這個時候其他線程執行數據更新語句(數據的增刪改),數據定義語句(建表、修改表結構等)等,都會被阻塞。

解鎖命令:

unlock tables

使用場景舉例:

主要應用于做全庫邏輯備份,原理也很簡單在全局鎖期間數據或表結構不會被更新,備份后文件的數據與預期也就一樣了。

當時加上全局鎖,意味著整個數據庫都是只讀狀態,如果備份時間過長就導致其他

Mysql中數據備份使用的命令是mysqldump命令

當使用參數-single-transaction的時候,導出數據之前就會啟動一個事務,來確保拿到一致性視圖,而由于MVCC的支持,這個過程中數據是可以正常更新的,因為讀取的數據在更新前已確認。

頁鎖

頁級鎖是 MySQL 中比較獨特的一種鎖定級別,主要應用于 BDB 存儲引擎,我們實際中基本上用的是InnoDB引擎,這里對頁鎖就不多展開了。

表鎖

MyISAM和InnoDB都支持表級鎖,但是InnoDB默認的是行級鎖。

表鎖下面又分了以下四種

圖片圖片

表鎖

顧名思義,就是直接對表進行加鎖,可以使用下面命令:

//加讀鎖
lock tables table_name read;
//加寫鎖
lock tables table_name write;
// 釋放當前會話的所有表鎖
unlock tables

如果加的是寫鎖,當對表進行寫操作時也會被阻塞,直到寫鎖被釋放。

不過盡量避免在使用 InnoDB 引擎的表使用表鎖,因為表鎖的顆粒度太大,會影響并發性能。

元數據鎖

MySQL5.5引入了元數據鎖(meta data lock - MDL),它不需要顯式使用,在訪問一個表的時候會被自動加上。

  • ? 對表數據進行 CRUD 操作時,加 MDL 讀鎖
  • ? 對表結構變更操作的時候,加 MDL 寫鎖

既然是自動加鎖,那釋放也是自動的!

事務執行期間,MDL 是一直持有的, 在事務提交后MDL才會釋放。

意向鎖(Intention Lock)

意向鎖主要是在對數據表的行記錄加共享鎖(S鎖)、獨占鎖(X鎖)之前,需要先在表級別加上一個意向鎖。

在InnoDB引擎中,當執行查詢操作,需要先對表加上「意向共享鎖」,然后對該記錄加【共享鎖】

意向鎖有兩種類型:

意向共享鎖(IS鎖):一個事務給一個數據行加共享鎖時,必須先獲得表的意向共享鎖

意向獨占鎖(IX鎖): 一個事務給一個數據行加獨占鎖時,必須先獲得表的意向獨占鎖

為什么需要先加意向鎖?

意向鎖的目的是更加快速的判斷數據表表里是否有記錄被加鎖。

比如我們要加【獨占表鎖】,先在表級別加了【意向獨占鎖】,那么在加【獨占鎖】時,直接查該表是否有意向獨占鎖,如果有就表示表記錄存在獨占鎖,這樣就不用去遍歷表記錄去查看行記錄是否存在獨占鎖了。

加鎖命令如下:

//加上意向共享鎖,然后對讀取的記錄加共享鎖
select ... lock in share mode;

//先表上加上意向獨占鎖,然后對讀取的記錄加獨占鎖
select ... for update;

AUTO-INC鎖

字面意思是用來控制自動自增的鎖?

是的,一般來說我們會在表中設置一個字段聲明 AUTO_INCREMENT 的自增ID字段。

AUTO-INC鎖在自增字段起了個什么作用呢?

當使用INSERT語句插入一條新記錄時,MySQL會自動為自增字段加鎖,防止其他并發的插入操作同時獲取相同的自增值。

其他事務要等待,直到執行完插入語句之后才會釋放鎖。

這就保證了數據表的 AUTO_INCREMENT 字段的值是連續遞增。

好吧,原來這個AUTO_INC鎖的作用是這樣的,以前我還一直不知道呢!

?? AUTO-INC鎖有什么問題?

大批量數據在一條語句中插入時(INSERT SELECT ),會帶來一些性能上的影響,從而阻塞其他事務的插入操作!

?? MySQL是如何進行AUTO-INC鎖性能優化的?

MYSQL 5.1.22版本開始,InnoDB存儲引擎使用一種輕量級互斥鎖(Mutex)來控制自增列增長

通過參數innodb_autoinc_lock_mode來控制 可以設定3個值分別是0,1,2

  • ? 0:traditional 每次insert都采用 AUTO-INC 鎖,語句執行結束后才釋放鎖,但并發能力較弱
  • ? 1:consecutive 對于SIMPLE INSERT,使用輕量級互斥鎖,對于BULK INSERT,使用AUTO-inc locking
  • ? 2:interleaved 采用輕量級鎖,申請自增主鍵后就釋放鎖,但可能會造成insert分配的id順序不一致

?? 一個事務中存在多個insert語句,auto-inc鎖是如何申請的?

自增鎖跟事務無關,即使多個insert語句在同一個十五中,每個insert還是都會申請罪行的自增鎖。

圖片圖片

行鎖

顧名思義,行鎖就是給數據庫表中每行數據加鎖,行鎖是加在索引上的

比如某個表中id字段是主鍵,如果給id=2這條記錄加鎖,那這把鎖是加在主鍵索引(聚簇索引)上的

行鎖使用分類

我們講表鎖的時候說到了意向鎖,在對數據表的行記錄加共享鎖(S鎖)、獨占鎖(X鎖)之前,需要先在表級別加上一個意向鎖 。

InnoDB 行級鎖按照使用方式分為:共享鎖(S鎖)、排它鎖(X鎖)

圖片圖片

讀鎖會阻塞寫(X),但是不會堵塞讀(S),而寫鎖則會把讀(S)和寫(X)都堵塞

對于普通 select 語句,innodb 不會加任何鎖。如果想在select操作的時候加上 S鎖 或者 X鎖,需要我們手動加鎖。

//查詢記錄加共享鎖
select ... lock in share mode;

//查詢記錄加獨占鎖
select ... for update;

InnoDB 在RR(MySQL默認隔離級別) ,對于 update、delete 和 insert 語句, 會自動給涉及的數據集加排它鎖(X)

InnoDB支持3種行鎖的算法,分別是:

  • ? Record Lock: 單個行記錄上的鎖

? Gap Lock: 間隙鎖,鎖定一個范圍,但不包含記錄本身

? Next-Key Lock: Gap Lock與Record Lock的結合,鎖定一個范圍,并且鎖定記錄本身

我們在分析行鎖三種算法是要結合存在共享鎖(S)和排他鎖(X)場景,我們接著看這三種

記錄鎖 Record Lock

Record Lock 稱為記錄鎖,鎖住的是一條記錄

SELECT * FROM `demo` WHERE `id`= 23 FOR UPDATE;

上面SQL在 id = 23 的記錄上加上記錄鎖(X鎖),這樣其他事務就無法插入,更新,刪除 id=23 這一行。

下面SQL是對主鍵索引 與 唯一索引 對數據行進行 UPDATE 操作時,也會對該行數據加記錄鎖:

UPDATE demo SET name = 'xiaoxu' WHERE id = 23;

記錄鎖是鎖住記錄,鎖住索引記錄,而不是真正的數據記錄。

?? 表中沒有建索引怎么辦?

即使該表上沒有任何索引,那么innodb會在后臺創建一個隱藏的聚集主鍵索引,那么鎖住的就是這個隱藏的聚集主鍵索引。

間隙鎖 GAP Lock

間隙鎖 是 InnoDB 在 RR(可重復讀) 隔離級別 下為了解決幻讀問題時引入的鎖機制。

Tips:使用間隙鎖GAP Lock鎖住的是一個區間,而不僅僅是這個區間中的每一條數據

SELECT * FROM demo WHERE id > 23 and id < 25 FOR UPDATE

上面語句對id范圍(23, 25)的數據行加間隙鎖鎖,此時就無法插入id= 24的數據

臨鍵鎖 Next-Key Lock

Next-key Lock 臨鍵鎖是記錄鎖和間隙鎖的組合,鎖的范圍是左開右閉區間的數據(即在某條記錄以及這條記錄前面間隙上的鎖)。

InnoDB是使用Next-Key Lock來解決幻讀問題的,在數據行上的非唯一索引列上都會存在一把臨鍵鎖。

注意:臨鍵鎖只與 非唯一索引列 有關,在 唯一索引列(包括主鍵列)上不存在臨鍵鎖。

圖片圖片

上面表結構中age字段為普通索引

-- 事務A 更新age=24的記錄 
UPDATE demo SET name = Vladimir WHERE age = 24;
-- 事務B 執行插入
INSERT INTO demo VALUES(100, 26, 'xiaoxu');

事務 A 在對 age 為 24 的列進行 UPDATE 操作的同時,也獲取了 (24, 26] 這個區間內的臨鍵鎖,所以此時事務B會被阻塞。

問題

臨鍵鎖 Next-Key Lock如何降級?

細心的朋友會發現開頭的題綱中有一個降級的指向,那么是在什么情況下發生降級的呢?

圖片圖片

在能使用記錄鎖或者間隙鎖就能避免幻讀現象的場景下, next-key lock 就會退化成記錄鎖或間隙鎖。

有以下場景:

唯一索引等值查詢:
1.當查詢的記錄是存在的,next-key lock 會退化成【記錄鎖】 2.當查詢的記錄是不存在的,next-key lock 會退化成【間隙鎖】

非唯一索引等值查詢:
1.當查詢的記錄存在時,除了會加 next-key lock 外,還額外加間隙鎖,也就是會加兩把鎖。
2.當查詢的記錄不存在時,只會加 next-key lock,然后會退化為間隙鎖,也就是只會加一把鎖。

責任編輯:武曉燕 來源: 小許code
相關推薦

2024-05-15 09:23:45

MySQL排他鎖共享鎖

2010-04-22 09:42:00

2025-02-10 09:58:48

2021-09-10 07:59:31

中斷鎖Java多線編程

2024-03-04 00:01:00

鎖表鎖行MySQL

2022-07-12 08:56:18

公平鎖非公平鎖Java

2024-04-03 14:56:12

生成式AI人工智能機器學習

2024-08-26 15:31:55

2022-05-09 07:37:04

Java非公平鎖公平鎖

2024-11-29 07:38:12

MySQL數據庫

2024-05-13 12:44:00

InnodbMySQL行級鎖

2024-05-15 09:41:22

樂觀鎖編程

2023-12-28 17:33:25

意向鎖MySQL開發者

2018-07-31 10:10:06

MySQLInnoDB死鎖

2025-06-04 02:55:00

MySQL意向鎖記錄鎖

2021-11-26 09:53:55

MYSQL開發數據庫

2019-01-04 11:18:35

獨享鎖共享鎖非公平鎖

2019-11-28 16:00:06

重入鎖讀寫鎖樂觀鎖

2020-10-20 13:50:47

MySQL數據庫

2010-05-24 12:50:59

MySQL表級鎖
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 久久久久亚洲 | 欧美日韩网站 | 国产日韩欧美精品一区二区三区 | 精品国产黄a∨片高清在线 www.一级片 国产欧美日韩综合精品一区二区 | 精品久久国产 | 最新中文在线视频 | 伊人手机在线视频 | 精品网 | 日韩久久久久久 | 亚洲综合色视频在线观看 | 欧美亚洲一区二区三区 | 呦呦在线视频 | 国产区一区二区三区 | 农夫在线精品视频免费观看 | 中文在线亚洲 | 精品国偷自产在线 | 91麻豆精品一区二区三区 | 中文字幕 在线观看 | 免费亚洲一区二区 | 日韩中文字幕在线观看 | 精品久久中文 | 女人牲交视频一级毛片 | 亚洲91精品| 国产精品久久久久久久模特 | 在线中文字幕第一页 | 日本一区二区三区四区 | 成人av电影天堂 | 国产不卡一区 | 夜夜爽99久久国产综合精品女不卡 | 成人免费区一区二区三区 | 日韩中文字幕在线视频观看 | 亚洲国产精久久久久久久 | 亚洲欧美网站 | 亚洲国产精品一区二区三区 | 精品久久香蕉国产线看观看亚洲 | 亚洲国产精品99久久久久久久久 | 国产精品一区二区三区在线 | 91精品久久久久久久久久入口 | 天堂一区二区三区 | 一本一道久久a久久精品综合蜜臀 | 在线亚洲一区二区 |