国产成人精品久久免费动漫-国产成人精品天堂-国产成人精品区在线观看-国产成人精品日本-a级毛片无码免费真人-a级毛片毛片免费观看久潮喷

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

Mysql技術(shù)內(nèi)幕之InnoDB鎖的深入講解

瀏覽:7日期:2023-10-07 15:48:55
前言

自7月份換工作以來(lái),期間一直在學(xué)習(xí)MySQL的相關(guān)知識(shí),聽(tīng)了一些視頻課,但是一直好奇那些講師的知識(shí)是從哪里學(xué)習(xí)的。于是想著從書(shū)籍中找答案。畢竟一直

看視頻也不是辦法,不能形成自己的知識(shí)。于是想著看書(shū)汲取知識(shí),看了幾本MySQL的相關(guān)書(shū)籍,包括《深入淺出Mysql》《高性能Mysql》《Mysql技術(shù)內(nèi)幕》,發(fā)現(xiàn)那些講

師講的內(nèi)容確實(shí)都在書(shū)上有出現(xiàn)過(guò),于是確信看書(shū)才是正確的汲取知識(shí)方式。本片主要記錄了Mysql的鎖機(jī)制的學(xué)習(xí)。

1.什么是鎖

鎖是計(jì)算機(jī)協(xié)調(diào)多個(gè)進(jìn)程或線程并發(fā)訪問(wèn)某一資源的機(jī)制。在數(shù)據(jù)庫(kù)中,除傳統(tǒng)的計(jì)算資源(如CPU、RAM、I/O等)的爭(zhēng)用以外,數(shù)據(jù)也是一種供許多用戶共享的資源。

如何保證數(shù)據(jù)并發(fā)訪問(wèn)的一致性、有效性是所有數(shù)據(jù)庫(kù)必須解決的一個(gè)問(wèn)題,鎖沖突也是影響數(shù)據(jù)庫(kù)并發(fā)訪問(wèn)性能的一個(gè)重要因素。

相對(duì)其他數(shù)據(jù)庫(kù)而言,MySQL 的鎖機(jī)制比較簡(jiǎn)單,其最顯著的特點(diǎn)是不同的存儲(chǔ)引擎支持不同的鎖機(jī)制。比如,MyISAM和MEMORY存儲(chǔ)引擎采用的是表級(jí)鎖(table-level

locking);BDB存儲(chǔ)引擎采用的是頁(yè)面鎖(page-levellocking),但也支持表級(jí)鎖;InnoDB存儲(chǔ)引擎既支持行級(jí)鎖(row-levellocking),也支持表級(jí)鎖,但默認(rèn)情況下是采用行級(jí)鎖。

MySQL這3種鎖的特性可大致歸納如下。

表級(jí)鎖:開(kāi)銷(xiāo)小,加鎖快;不會(huì)出現(xiàn)死鎖;鎖定粒度大,發(fā)生鎖沖突的概率最高,并發(fā)度最低。 行級(jí)鎖:開(kāi)銷(xiāo)大,加鎖慢;會(huì)出現(xiàn)死鎖;鎖定粒度最小,發(fā)生鎖沖突的概率最低,并發(fā)度也最高。 頁(yè)面鎖:開(kāi)銷(xiāo)和加鎖時(shí)間界于表鎖和行鎖之間;會(huì)出現(xiàn)死鎖;鎖定粒度界于表鎖和行鎖之間,并發(fā)度一般。

3種鎖的使用角度:

表級(jí)鎖更適合于以查詢?yōu)橹鳎挥猩倭堪此饕龡l件更新數(shù)據(jù)的應(yīng)用,如Web應(yīng)用; 行級(jí)鎖則更適合于有大量按索引條件并發(fā)更新少量不同數(shù)據(jù),同時(shí)又有并發(fā)查詢的應(yīng)用,如一些在線事務(wù)處理(OLTP)系統(tǒng)。 BDB的頁(yè)面鎖已經(jīng)被InnoDB取代,不做討論。2.InnoDB存儲(chǔ)引擎中的鎖2.1鎖的類(lèi)型

InnoDB存儲(chǔ)引擎實(shí)現(xiàn)了如下兩種標(biāo)準(zhǔn)的行級(jí)鎖:

共享鎖(S Lock),允許事務(wù)讀一行數(shù)據(jù)。 排他鎖(X Lock),允許事務(wù)刪除或更新一行數(shù)據(jù)。

如果一個(gè)事務(wù)T1已經(jīng)獲得了行r的共享鎖,那么另外的事務(wù)T2可以立即獲得行r的共享鎖,因?yàn)樽x取沒(méi)有改變行r的數(shù)據(jù),稱(chēng)這種情況

為鎖兼容(Lock Compatible)。但若有其他的事務(wù)T3想獲得行r的排他鎖,則其必須等待事務(wù)T1、T2釋放行r的共享鎖——這種情況稱(chēng)為鎖不兼容。

X S X 不兼容 不兼容 S 不兼容 兼容

此外,InnoDB存儲(chǔ)引擎支持多粒度鎖定,這種鎖定允許事務(wù)在行級(jí)上鎖和表鎖上的鎖同時(shí)存在。為了支持在不同粒度上進(jìn)行加鎖操作,InnoDB存

儲(chǔ)引擎支持一種額外的鎖方式,稱(chēng)之為意向鎖。意向鎖是將鎖定的對(duì)象分為多個(gè)層次,意向鎖意味著事務(wù)希望在更細(xì)粒度上進(jìn)行加鎖。 ​ InnoDB存

儲(chǔ)引擎支持意向鎖設(shè)計(jì)比較簡(jiǎn)練,其意向鎖即為表級(jí)別的鎖。設(shè)計(jì)目的主要是為了在一個(gè)事務(wù)中揭示下一行將被請(qǐng)求的鎖類(lèi)型。其支持兩種意向鎖:

意向共享鎖(IS Lock),事務(wù)想要獲得一張表中某幾行的共享鎖 意向排他鎖(IX Lock),事務(wù)想要獲得一張表中某幾行的排他鎖2.2 一致性非鎖定讀

一致性的非鎖定讀(consistant nonlocking read)是指InnoDB存儲(chǔ)引擎通過(guò)多版本控制(multi versioning)的方法來(lái)讀取當(dāng)前執(zhí)行時(shí)間數(shù)據(jù)庫(kù)中行的

數(shù)據(jù)。如果讀取的行正在執(zhí)行Delete或Update操作,這時(shí)讀取操作不會(huì)因此去等待行上鎖的釋放。相反地,InnoDB存儲(chǔ)引擎會(huì)去讀取行的一個(gè)快照

版本。如下如所示。

Mysql技術(shù)內(nèi)幕之InnoDB鎖的深入講解

上圖直觀地展現(xiàn)了InnoDB存儲(chǔ)引擎一致性的非鎖定讀。之所以稱(chēng)為非鎖定讀,因?yàn)椴恍枰却L問(wèn)的行上X鎖的釋放。快照數(shù)據(jù)是指該行的之前版本

的數(shù)據(jù),該實(shí)現(xiàn)是通過(guò)undo段來(lái)完成。而undo用來(lái)在事務(wù)中回滾數(shù)據(jù),因此快照數(shù)據(jù)本身是沒(méi)有額外的開(kāi)銷(xiāo)。此外,讀取快照數(shù)據(jù)是不需要上鎖的,

因?yàn)闆](méi)有事務(wù)需要對(duì)歷史的數(shù)據(jù)進(jìn)行修改操作。

通過(guò)上圖可以知道,快照數(shù)據(jù)其實(shí)就是當(dāng)前行數(shù)據(jù)之前的歷史版本,每行記錄可能有多個(gè)版本,一般稱(chēng)這種技術(shù)為行多版本技術(shù)。由此帶來(lái)的并發(fā)控制,

稱(chēng)之為多版本并發(fā)控制(Multi Version Concurrency Control, MVCC)。

在事務(wù)隔離級(jí)別READ COMMITTED和REPEATABLE READ下,InnoDB存儲(chǔ)引擎使用非鎖定的一致性讀。然而,對(duì)于快照數(shù)據(jù)的定義卻不相同。在READ

COMMITTED事務(wù)隔離級(jí)別下,對(duì)于快照數(shù)據(jù),非一致性讀總是讀取被鎖定行的最新一份快照數(shù)據(jù)。而在REPEATABLE READ事務(wù)隔離級(jí)別下,對(duì)于快照

數(shù)據(jù),非一致性讀總是讀取事務(wù)開(kāi)始時(shí)的行數(shù)據(jù)版本。如下表所示示例:

時(shí)間 會(huì)話A 會(huì)話B 1 begin 2 select * from t_user where id = 1; 3 begin 4 update t_user set id = 10 where id = 1; 5 select * from t_user where id = 1; 6 commit; 7 select * from t_user where id = 1; 8 commit;

假設(shè)原本id = 1的記錄是存在的,大家可以按上表時(shí)間順序執(zhí)行對(duì)應(yīng)的會(huì)話,比較及驗(yàn)證2者的不同。

2.3 一致性鎖定讀

在默認(rèn)配置下,在事務(wù)的隔離級(jí)別為REPEATABLE READ模式下,InnoDB存儲(chǔ)引擎的select操作使用一致性非鎖定讀。但是在某些情況下,用戶需要顯示地

對(duì)數(shù)據(jù)庫(kù)讀取操作進(jìn)行加鎖以保證數(shù)據(jù)邏輯的一致性。而這要求數(shù)據(jù)庫(kù)支持加鎖語(yǔ)句,即使時(shí)對(duì)于select的只讀操作。InnoDB存儲(chǔ)引擎對(duì)于select語(yǔ)句支持兩

種一致性的鎖定讀(locking read)操作:

select ··· for update select ··· lock in share mode

select ··· for update對(duì)讀取的行記錄加一個(gè)X鎖,其他事務(wù)不能對(duì)已鎖定的行加上任何鎖。select ··· lock in share mode對(duì)讀取的行記錄加一個(gè)S鎖,其他事務(wù)可

以向被鎖定的行加S鎖,但是如果加X(jué)鎖,則會(huì)被阻塞。

對(duì)于一致性非鎖定讀,即使讀取的行已被執(zhí)行了select ··· for update,也是可以進(jìn)行讀取的。此外,select ··· for update或者select ··· lock in share mode必須在

一個(gè)事務(wù)中,當(dāng)事務(wù)提交了,鎖也就釋放了。因此在使用上述兩種select鎖定語(yǔ)句時(shí),務(wù)必加上begin,start transaction或者set autocommit=0。

3 鎖的算法3.1行鎖的3中算法

InnoDB存儲(chǔ)引擎有3種行鎖的算法,其分別是:

Record Lock:?jiǎn)蝹€(gè)行記錄上的鎖 Gap Lock:間隙鎖,鎖定一個(gè)范圍,但不包含記錄本身 Next-Key Lock:Gap Lock + Record Lock,鎖定一個(gè)范圍,并且鎖定記錄本身

Record Lock總是會(huì)去鎖住主鍵索引記錄,如果InnoDB存儲(chǔ)引擎表在建立的時(shí)候沒(méi)有設(shè)置任何一個(gè)主鍵或唯一非空索引,那么這時(shí)InnoDB存儲(chǔ)引擎會(huì)使用隱式的

主鍵來(lái)進(jìn)行鎖定。

Next-Key Lock是結(jié)合了Gap Lock+Record Lock的一種鎖定算法,在Next-Key Lock算法下,InnoDB對(duì)于行的查詢都是采用這種鎖定算法。假如一個(gè)索引有10,11

,13和20這4個(gè)值,那么該索引可能被Next-Key Locking的區(qū)間為:

(-無(wú)窮,10] ,(10,11], (11,13], (13,20], (20,+無(wú)窮)

采用Next-Key Lock的鎖定技術(shù)稱(chēng)為Next-Key Locking。其設(shè)計(jì)的目的是為了解決幻讀問(wèn)題。而利用這種鎖定技術(shù),鎖定的不是單個(gè)值,而是一個(gè)范圍。 ​ 然而,

當(dāng)查詢的索引含有唯一屬性時(shí),InnoDB存儲(chǔ)引擎會(huì)對(duì)Next-Key Lock進(jìn)行優(yōu)化將其降級(jí)為Record Lock,即僅鎖住索引本身,而不是范圍。下面演示一個(gè)例子。

mysql> create table t (a int primary key);Query OK, 0 rows affected (0.01 sec)​mysql> insert into t select 1;Query OK, 1 row affected (0.00 sec)Records: 1 Duplicates: 0 Warnings: 0​mysql> insert into t select 2;Query OK, 1 row affected (0.00 sec)Records: 1 Duplicates: 0 Warnings: 0​mysql> insert into t select 5;Query OK, 1 row affected (0.01 sec)Records: 1 Duplicates: 0 Warnings: 0

接著按下表時(shí)間順序執(zhí)行操作。

時(shí)間 會(huì)話A 會(huì)話B 1 begin; 2 select * from t where a = 5 for update; 3 begin; 4 insert into t select 4; 5 commit; #成功,不需要等待 6 commit;

表t共有1,2,5三個(gè)值。在上面的例子中,在會(huì)話A中首先對(duì)a=5進(jìn)行X鎖定。而由于a是主鍵且唯一,因此鎖定的僅是5這個(gè)值,而不是(2,5)這個(gè)范圍,這樣在會(huì)話

B中插入值4而不會(huì)阻塞,可以立即插入并返回。即鎖定由Next-Key Lock算法降級(jí)為了Record Lock,從而提高應(yīng)用的并發(fā)性。

如上,Next-Key Lock降級(jí)為Record Lock僅在查詢的列是唯一索引的情況下。若是輔助索引,則情況會(huì)完全不同。同樣,首先創(chuàng)建測(cè)試表z進(jìn)行測(cè)試:

mysql> create table z (a int ,b int ,primary key(a), key(b));mysql> insert into z select 1,1;mysql> insert into z select 3,1;mysql> insert into z select 5,3;mysql> insert into z select 7,6;mysql> insert into z select 10,8;

表z的列b是輔助索引,若在會(huì)話A中執(zhí)行下面的SQL語(yǔ)句:

mysql> select * from z where b = 3 for update;

很明顯,這時(shí)SQL語(yǔ)句通過(guò)索引列b進(jìn)行查詢,因此其使用傳統(tǒng)的Next-Key Locking技術(shù)加鎖,并且由于有兩個(gè)索引,其需要分別進(jìn)行鎖定。對(duì)于聚集索引,其僅對(duì)列

a等于5的索引加上Record Lock。而對(duì)于輔助索引,其加上的是Next-Key Lock,鎖定的范圍是(1,3),特別需要注意的是,InnoDB存儲(chǔ)引擎還會(huì)對(duì)輔助索引下一個(gè)

鍵值加上gap lock,即還有一個(gè)輔助索引范圍為(3,6)的鎖。因此,若在新會(huì)話B中運(yùn)行下面的SQL語(yǔ)句,都會(huì)被阻塞:

mysql> select * from z where a = 5 lock in share mode;mysql> insert into z select 4,2;mysql> insert into z select 6,5;

第一個(gè)SQL語(yǔ)句不能執(zhí)行,因?yàn)樵跁?huì)話A中執(zhí)行的SQL語(yǔ)句已經(jīng)對(duì)聚集索引中列a=5的值加上X鎖,因此執(zhí)行會(huì)被阻塞。第二個(gè)SQL語(yǔ)句,主鍵插入4,沒(méi)有問(wèn)題,但是插入

的輔助索引值2在鎖定的范圍(1,3)中,因此執(zhí)行同樣會(huì)被阻塞。第三個(gè)SQL語(yǔ)句,插入的主鍵6沒(méi)有被鎖定,5也不在范圍(1,3)之間。但插入的值5在另一個(gè)鎖定的

范圍(3,6)中,故同樣需要等待。而下面的SQL語(yǔ)句,不會(huì)被阻塞,可以立即執(zhí)行:

mysql> insert into z select 8,6;mysql> insert into z select 2,0;mysql> insert into z select 6,7;

從上面的例子可以看到,Gap Lock的作用是為了阻止多個(gè)事務(wù)將記錄插入到同一個(gè)范圍內(nèi),而這會(huì)導(dǎo)致幻讀問(wèn)題的產(chǎn)生。假如在上面的例子中,會(huì)話A中用戶已經(jīng)鎖定了

b=3的記錄。若此時(shí)沒(méi)有Gap Lock鎖定(3,6),那么用戶可以插入索引b列為3的記錄,這會(huì)導(dǎo)致會(huì)話A中的用戶再次執(zhí)行同樣查詢時(shí)會(huì)返回不同的記錄,即幻讀。

這里主要探究的是InnoDB存儲(chǔ)引擎鎖表的機(jī)制,至少自己明白了Mysql的行鎖機(jī)制,不知道讀者是否有疑問(wèn),歡迎留言。下次會(huì)記錄關(guān)于Mysql事務(wù)特性及其內(nèi)部的實(shí)現(xiàn)機(jī)制,

包括mysql的內(nèi)部架構(gòu),InnoDB buffer Pool,redo log, undo log等具體的詳解,目前只是對(duì)知識(shí)過(guò)了一遍,但還未總結(jié)。

總結(jié)

到此這篇關(guān)于Mysql技術(shù)內(nèi)幕之InnoDB鎖的文章就介紹到這了,更多相關(guān)Mysql InnoDB鎖內(nèi)容請(qǐng)搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持好吧啦網(wǎng)!

標(biāo)簽: MySQL 數(shù)據(jù)庫(kù)
相關(guān)文章:
主站蜘蛛池模板: 国产v片成人影院在线观看 国产v片在线播放免费观 | 久久草在线精品 | 在线欧美一级毛片免费观看 | 亚洲精品一区二区三区五区 | 亚洲人成在线播放网站岛国 | 亚欧精品一区二区三区 | 日韩精品一区二区三区在线观看 | 久草免费在线视频观看 | 国产人成精品综合欧美成人 | 午夜爱爱毛片xxxx视频免费看 | 久久香蕉国产线看观看亚洲片 | 欧美三级不卡视频 | 99久久精品免费视频 | 天堂素人搭讪系列嫩模在线观看 | 欧产日产国产精品精品 | 国产欧美一区二区三区观看 | 欧美视频在线一区 | 亚洲巨乳自拍在线视频 | 亚洲欧美一二三区 | 欧美日韩中文国产一区二区三区 | 久久99精品久久久久久 | a毛片基地免费全部香蕉 | 欧美特黄一级高清免费的香蕉 | 欧美日本免费观看αv片 | 国产在线精品一区免费香蕉 | 国内自拍视频在线看免费观看 | 国产成人精品久久二区二区 | 久草在线中文 | 久久国产三级 | 成人午夜两性视频免费看 | 亚洲欧美日韩国产专区一区 | 在线中文字日产幕 | 国产精品无码久久综合网 | 国产精品久久久久久 | 国产97公开成人免费视频 | 亚洲精品国产成人99久久 | 国产成人亚洲精品无广告 | 在线久草 | 欧美一区二区三区男人的天堂 | 午夜毛片免费观看视频 | 免费看特级淫片日本 |