欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

MySQL知識(shí)點(diǎn)之InnoDB中的行級(jí)鎖是什么

今天小編給大家分享一下MySQL知識(shí)點(diǎn)之InnoDB中的行級(jí)鎖是什么的相關(guān)知識(shí)點(diǎn),內(nèi)容詳細(xì),邏輯清晰,相信大部分人都還太了解這方面的知識(shí),所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。

成都創(chuàng)新互聯(lián)致力于成都網(wǎng)站建設(shè)、網(wǎng)站設(shè)計(jì),成都網(wǎng)站設(shè)計(jì),集團(tuán)網(wǎng)站建設(shè)等服務(wù)標(biāo)準(zhǔn)化,推過標(biāo)準(zhǔn)化降低中小企業(yè)的建站的成本,并持續(xù)提升建站的定制化服務(wù)水平進(jìn)行質(zhì)量交付,讓企業(yè)網(wǎng)站從市場競爭中脫穎而出。 選擇成都創(chuàng)新互聯(lián),就選擇了安全、穩(wěn)定、美觀的網(wǎng)站建設(shè)服務(wù)!

MySQL知識(shí)點(diǎn)之InnoDB中的行級(jí)鎖是什么

行鎖,也稱為記錄鎖,顧名思義就是在記錄上加的鎖。但是要注意,這個(gè)記錄指的是通過給索引上的索引項(xiàng)加鎖。InnoDB 這種行鎖實(shí)現(xiàn)特點(diǎn)意味著:只有通過索引條件檢索數(shù)據(jù),InnoDB才使用行級(jí)鎖,否則,InnoDB將使用表鎖。

不論是使用主鍵索引、唯一索引或普通索引,InnoDB都會(huì)使用行鎖來對(duì)數(shù)據(jù)加鎖。

只有執(zhí)行計(jì)劃真正使用了索引,才能使用行鎖:即便在條件中使用了索引字段,但是否使用索引來檢索數(shù)據(jù)是由MySQL 通過判斷不同執(zhí)行計(jì)劃的代價(jià)來決定的,如果MySQL認(rèn)為全表掃描效率更高,比如對(duì)一些很小的表,它就不會(huì)使用索引,這種情況下InnoDB將使用表鎖,而不是行鎖。

同時(shí)當(dāng)我們用范圍條件而不是相等條件檢索數(shù)據(jù),并請(qǐng)求鎖時(shí),InnoDB會(huì)給符合條件的已有數(shù)據(jù)記錄的索引項(xiàng)加鎖。

不過即使是行鎖,InnoDB里也是分成了各種類型的。換句話說即使對(duì)同一條記錄加行鎖,如果類型不同,起到的功效也是不同的。

這里我們還是使用前面的teacher表,增加一個(gè)索引,并插入幾條記錄。

mysql> desc teacher;
+--------+--------------+------+-----+---------+-------+
| Field  | Type         | Null | Key | Default | Extra |
+--------+--------------+------+-----+---------+-------+
| number | int(11)      | NO   | PRI | NULL    |       |
| name   | varchar(100) | YES  | MUL | NULL    |       |
| domain | varchar(100) | YES  |     | NULL    |       |
+--------+--------------+------+-----+---------+-------+
3 rows in set (0.00 sec)

mysql> select * from teacher;
+--------+------+--------+
| number | name | domain |
+--------+------+--------+
|      1 | T    | Java   |
|      3 | M    | redis  |
|      9 | X    | MQ     |
|     15 | O    | Python |
|     21 | A    | Golang |
+--------+------+--------+
5 rows in set (0.00 sec)

我們來看看都有哪些常用的行鎖類型。

Record Locks

也叫記錄鎖,就是僅僅把一條記錄鎖上,官方的類型名稱為:LOCK_REC_NOT_GAP。比方說我們把number值為9的那條記錄加一個(gè)記錄鎖的示意圖如下:

MySQL知識(shí)點(diǎn)之InnoDB中的行級(jí)鎖是什么

記錄鎖是有S鎖和X鎖之分的,當(dāng)一個(gè)事務(wù)獲取了一條記錄的S型記錄鎖后,其他事務(wù)也可以繼續(xù)獲取該記錄的S型記錄鎖,但不可以繼續(xù)獲取X型記錄鎖;當(dāng)一個(gè)事務(wù)獲取了一條記錄的X型記錄鎖后,其他事務(wù)既不可以繼續(xù)獲取該記錄的S型記錄鎖,也不可以繼續(xù)獲取X型記錄鎖。

T1T2
begin;
select * from teacher where number=9 for update;

select * from teacher where number=9 for update; # 阻塞

Gap Locks

MySQL在REPEATABLE READ隔離級(jí)別下是可以部分解決幻讀問題的,解決方案有兩種,可以使用MVCC方案解決,也可以采用加鎖方案解決。但是在使用加鎖方案解決時(shí)有問題,就是事務(wù)在第一次執(zhí)行讀取操作時(shí),那些幻影記錄尚不存在,我們無法給這些幻影記錄加上記錄鎖。InnoDB提出了一種稱之為Gap Locks的鎖,官方的類型名稱為:LOCK_GAP,我們也可以簡稱為gap鎖。

間隙鎖實(shí)質(zhì)上是對(duì)索引前后的間隙上鎖,不對(duì)索引本身上鎖。

T1T2
begin;
update teacher set domain=‘Redis’ where name=‘M’;

insert into teacher value(23,‘B’,‘docker’); # 阻塞

insert into teacher value(23,‘B’,‘docker’); # 阻塞

事務(wù)T1會(huì)對(duì)([A, 21], [M, 3])、([M, 3], [O, 15])之間進(jìn)行上gap鎖,如下圖中所示:

MySQL知識(shí)點(diǎn)之InnoDB中的行級(jí)鎖是什么

意味著不允許別的事務(wù)在這條記錄前后間隙插入新記錄,所以T2就不能插入。

但是當(dāng)SQL語句變?yōu)椋?/p>

insert into teacher value(70,'P','docker');

能插入嗎?當(dāng)然能,因?yàn)椋?0,‘P’)這條記錄不在被鎖的區(qū)間內(nèi)。

思考題

現(xiàn)在有表,表中有記錄如下:

list = ['su liang','hacker','ice']
list.insert(1,'kiko')
print(list)
#結(jié)果:['su liang', 'kiko', 'hacker', 'ice']

開啟一個(gè)事務(wù):

begin;SELECT * FROM test1 WHERE number = 3 FOR UPDATE;

開啟另外一個(gè)事務(wù):

INSERT INTO test1 (id, number) VALUES (2, 1); # 阻塞
INSERT INTO test1 (id, number) VALUES (3, 2); # 阻塞
INSERT INTO test1 (id, number) VALUES (6, 8); # 阻塞
INSERT INTO test1 (id, number) VALUES (8, 8); # 正常執(zhí)行
INSERT INTO test1 (id, number) VALUES (9, 9); # 正常執(zhí)行
INSERT INTO test1 (id, number) VALUES (10, 12); # 正常執(zhí)行
UPDATE test1 SET number = 5 WHERE id = 11 AND number = 12; # 阻塞

為什么(6,8)不能執(zhí)行,(8,8)可以執(zhí)行?這個(gè)間隙鎖的范圍應(yīng)該是[1,8],最后一個(gè)語句為什么不能執(zhí)行?
解決思路:畫一個(gè)number的索引數(shù)據(jù)存放的圖,然后根據(jù)間隙鎖的加鎖方式,把鎖加上,就能很快明白答案。

MySQL知識(shí)點(diǎn)之InnoDB中的行級(jí)鎖是什么

  1. 當(dāng)插入的number在(1,8)區(qū)間都會(huì)被阻塞

  2. 當(dāng)插入的number等于1、8,那么id在(1,4]、[6,7)區(qū)間會(huì)被阻塞

Next-Key Locks

有時(shí)候我們既想鎖住某條記錄,又想阻止其他事務(wù)在該記錄前邊的間隙插入新記錄,所以InnoDB就提出了一種稱之為Next-Key Locks的鎖,官方的類型名稱為:LOCK_ORDINARY,我們也可以簡稱為next-key鎖。next-key鎖的本質(zhì)就是
一個(gè)記錄鎖和一個(gè)gap鎖的合體。

默認(rèn)情況下,InnoDB以REPEATABLE READ隔離級(jí)別運(yùn)行。在這種情況下,InnoDB使用Next-Key Locks鎖進(jìn)行搜索和索引掃描,這可以防止幻讀的發(fā)生。

Insert Intention Locks

我們說一個(gè)事務(wù)在插入一條記錄時(shí)需要判斷一下插入位置是不是被別的事務(wù)加了所謂的gap鎖(next-key鎖也包含gap 鎖,后邊就不強(qiáng)調(diào)了),如果有的話,插入操作需要等待,直到擁有g(shù)ap鎖的那個(gè)事務(wù)提交。

但是InnoDB規(guī)定事務(wù)在等待的時(shí)候也需要在內(nèi)存中生成一個(gè)鎖結(jié)構(gòu),表明有事務(wù)想在某個(gè)間隙中插入新記錄,但是現(xiàn)在處于等待狀態(tài)。這種類型的鎖命名為Insert Intention Locks,官方的類型名稱為:LOCK_INSERT_INTENTION,我們也可以稱為插入意向鎖。

可以理解為插入意向鎖是一種鎖的的等待隊(duì)列,讓等鎖的事務(wù)在內(nèi)存中進(jìn)行排隊(duì)等待,當(dāng)持有鎖的事務(wù)完成后,處于等待狀態(tài)的事務(wù)就可以獲得鎖繼續(xù)事務(wù)了。

隱式鎖

鎖的的維護(hù)是需要成本的,為了節(jié)約資源,MySQL在設(shè)計(jì)提出了了一個(gè)隱式鎖的概念。一般情況下INSERT操作是不加鎖的,當(dāng)然真的有并發(fā)沖突的情況下下,還是會(huì)導(dǎo)致問題的。

所以MySQL中,一個(gè)事務(wù)對(duì)新插入的記錄可以不顯式的加鎖,但是別的事務(wù)在對(duì)這條記錄加S鎖或者X鎖時(shí),會(huì)去檢查索引記錄中的trx_id隱藏列,然后進(jìn)行各種判斷,會(huì)先幫助當(dāng)前事務(wù)生成一個(gè)鎖結(jié)構(gòu),然后自己再生成一個(gè)鎖結(jié)構(gòu)后進(jìn)入等待狀態(tài)。但是由于事務(wù)id的存在,相當(dāng)于加了一個(gè)隱式鎖。

這樣的話,隱式鎖就起到了延遲生成鎖的用處。這個(gè)過程,我們無法干預(yù),是由引擎自動(dòng)處理的,對(duì)我們是完全透明的,我們知道下就行了。

鎖的內(nèi)存結(jié)構(gòu)

所謂的鎖其實(shí)是一個(gè)內(nèi)存中的結(jié)構(gòu),在事務(wù)執(zhí)行前本來是沒有鎖的,也就是說一開始是沒有鎖結(jié)構(gòu)和記錄進(jìn)行關(guān)聯(lián)的,當(dāng)一個(gè)事務(wù)想對(duì)這條記錄做改動(dòng)時(shí),首先會(huì)看看內(nèi)存中有沒有與這條記錄關(guān)聯(lián)的鎖結(jié)構(gòu),當(dāng)沒有的時(shí)候就會(huì)在內(nèi)存中生成一個(gè)鎖結(jié)構(gòu)與之關(guān)聯(lián)。比方說事務(wù)T1要對(duì)記錄做改動(dòng),就需要生成一個(gè)鎖結(jié)構(gòu)與之關(guān)聯(lián)。

鎖結(jié)構(gòu)里至少要有兩個(gè)比較重要的屬性:

  • trx 信息:代表這個(gè)鎖結(jié)構(gòu)是哪個(gè)事務(wù)生成的。

  • is_waiting:代表當(dāng)前事務(wù)是否在等待。

MySQL知識(shí)點(diǎn)之InnoDB中的行級(jí)鎖是什么

當(dāng)事務(wù)T1改動(dòng)了條記錄后,就生成了一個(gè)鎖結(jié)構(gòu)與該記錄關(guān)聯(lián),因?yàn)橹皼]有別的事務(wù)為這條記錄加鎖,所以is_waiting 屬性就是false,我們把這個(gè)場景就稱之為獲取鎖成功,或者加鎖成功,然后就可以繼續(xù)執(zhí)行操作了。

在事務(wù)T1提交之前,另一個(gè)事務(wù)T2也想對(duì)該記錄做改動(dòng),那么先去看看有沒有鎖結(jié)構(gòu)與這條記錄關(guān)聯(lián),發(fā)現(xiàn)有一個(gè)鎖結(jié)構(gòu)與之關(guān)聯(lián)后,然后也生成了一個(gè)鎖結(jié)構(gòu)與這條記錄關(guān)聯(lián),不過鎖結(jié)構(gòu)的is_waiting屬性值為true,表示當(dāng)前事務(wù)需要等待,我們把這個(gè)場景就稱之為獲取鎖失敗,或者加鎖失敗,或者沒有成功的獲取到鎖。

在事務(wù)T1提交之后,就會(huì)把該事務(wù)生成的鎖結(jié)構(gòu)釋放掉,然后看看還有沒有別的事務(wù)在等待獲取鎖,發(fā)現(xiàn)了事務(wù)T2還在等待獲取鎖,所以把事務(wù)T2對(duì)應(yīng)的鎖結(jié)構(gòu)的is_waiting屬性設(shè)置為false,然后把該事務(wù)對(duì)應(yīng)的線程喚醒,讓它繼續(xù)執(zhí)行,此時(shí)事務(wù)T2就算獲取到鎖了。這種實(shí)現(xiàn)方式非常像并發(fā)編程里AQS的等待隊(duì)列。

對(duì)一條記錄加鎖的本質(zhì)就是在內(nèi)存中創(chuàng)建一個(gè)鎖結(jié)構(gòu)與之關(guān)聯(lián)。那么,一個(gè)事務(wù)對(duì)多條記錄加鎖時(shí),是不是就要?jiǎng)?chuàng)建多個(gè)鎖結(jié)構(gòu)呢?比如:

SELECT * FROM teacher LOCK IN SHARE MODE;

很顯然,這條語句需要為teacher表中的所有記錄進(jìn)行加鎖。那么,是不是需要為每條記錄都生成一個(gè)鎖結(jié)構(gòu)呢?其實(shí)理論上創(chuàng)建多個(gè)鎖結(jié)構(gòu)沒有問題,反而更容易理解。但是如果一個(gè)事務(wù)要獲取10,000條記錄的鎖,要生成10,000個(gè)這樣的結(jié)構(gòu),不管是執(zhí)行效率還是空間效率來說都是很不劃算的,所以實(shí)際上,并不是一個(gè)記錄一個(gè)鎖結(jié)構(gòu)。

當(dāng)然鎖結(jié)構(gòu)實(shí)際是很復(fù)雜的,我們大概了解下里面包含哪些元素。

  • 鎖所在的事務(wù)信息:無論是表級(jí)鎖還是行級(jí)鎖,一個(gè)鎖屬于一個(gè)事務(wù),這里記載著該鎖對(duì)應(yīng)的事務(wù)信息。

  • 索引信息:對(duì)于行級(jí)鎖來說,需要記錄一下加鎖的記錄屬于哪個(gè)索引。

  • 表鎖/行鎖信息:表級(jí)鎖結(jié)構(gòu)和行級(jí)鎖結(jié)構(gòu)在這個(gè)位置的內(nèi)容是不同的。具體表現(xiàn)為表級(jí)鎖記載著這是對(duì)哪個(gè)表加的鎖,還有其他的一些信息;而行級(jí)鎖記載了記錄所在的表空間、記錄所在的頁號(hào)、區(qū)分到底是為哪一條記錄加了鎖的數(shù)據(jù)結(jié)構(gòu)。

  • 鎖模式:鎖是IS,IX,S,X 中的哪一種。
    鎖類型:表鎖還是行鎖,行鎖的具體類型。

  • 其他:一些和鎖管理相關(guān)的數(shù)據(jù)結(jié)構(gòu),比如哈希表和鏈表等。

基本上來說,同一個(gè)事務(wù)里,同一個(gè)數(shù)據(jù)頁面,同一個(gè)加鎖類型的鎖會(huì)保存在一起。

以上就是“MySQL知識(shí)點(diǎn)之InnoDB中的行級(jí)鎖是什么”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會(huì)為大家更新不同的知識(shí),如果還想學(xué)習(xí)更多的知識(shí),請(qǐng)關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。

網(wǎng)站欄目:MySQL知識(shí)點(diǎn)之InnoDB中的行級(jí)鎖是什么
新聞來源:http://chinadenli.net/article14/iejoge.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供微信小程序、微信公眾號(hào)外貿(mào)建站、動(dòng)態(tài)網(wǎng)站、用戶體驗(yàn)、服務(wù)器托管

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

h5響應(yīng)式網(wǎng)站建設(shè)
大香蕉网国产在线观看av| 亚洲中文字幕在线综合视频| 九九蜜桃视频香蕉视频| 亚洲国产成人久久99精品| 好吊妞视频免费在线观看| 久久99青青精品免费观看| 99久久精品午夜一区二区| 三级高清有码在线观看| 中文字幕亚洲人妻在线视频| 日本精品最新字幕视频播放| 91精品日本在线视频| 熟女中文字幕一区二区三区| 国产在线日韩精品欧美| 美女被啪的视频在线观看| 区一区二区三中文字幕| 日本欧美一区二区三区就| 国产欧美日韩在线精品一二区| 亚洲专区一区中文字幕| 中国美女偷拍福利视频| 麻豆视频传媒入口在线看| 国产熟女一区二区三区四区| 中国黄色色片色哟哟哟哟哟哟| 日本一二三区不卡免费| 国产一区二区三区四区中文| 久草精品视频精品视频精品| 中文字幕久久精品亚洲乱码| 亚洲高清中文字幕一区二三区| 国产精品内射视频免费| 十八禁日本一区二区三区| 欧美成人精品一区二区久久| 性欧美唯美尤物另类视频 | 激情国产白嫩美女在线观看| 黄色激情视频中文字幕| 我想看亚洲一级黄色录像| 国产不卡免费高清视频| 青青操成人免费在线视频| 亚洲精品小视频在线观看| 在线观看日韩欧美综合黄片| 成年人免费看国产视频| 亚洲中文字幕熟女丝袜久久| 中文字幕精品一区二区年下载|