真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

MySQL鎖機(jī)制的示例分析

這篇文章主要介紹了MySQL鎖機(jī)制的示例分析,具有一定借鑒價(jià)值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。

創(chuàng)新互聯(lián)公司始終堅(jiān)持【策劃先行,效果至上】的經(jīng)營(yíng)理念,通過(guò)多達(dá)10余年累計(jì)超上千家客戶(hù)的網(wǎng)站建設(shè)總結(jié)了一套系統(tǒng)有效的全網(wǎng)營(yíng)銷(xiāo)推廣解決方案,現(xiàn)已廣泛運(yùn)用于各行各業(yè)的客戶(hù),其中包括:電動(dòng)窗簾等企業(yè),備受客戶(hù)贊揚(yáng)。

鎖在MySQL中是非常重要的一部分,鎖對(duì)MySQL的數(shù)據(jù)訪(fǎng)問(wèn)并發(fā)有著舉足輕重的影響。鎖涉及到的知識(shí)篇幅也很多,所以要啃完并消化到自己的肚子里,是需要靜下心好好反反復(fù)復(fù)幾遍地細(xì)細(xì)品味。本文是對(duì)鎖的一個(gè)大概的整理,一些相關(guān)深入的細(xì)節(jié),還是需要找到相關(guān)書(shū)籍來(lái)繼續(xù)夯實(shí)。

MySQL鎖機(jī)制的示例分析

鎖的認(rèn)識(shí)

1.1 鎖的解釋

計(jì)算機(jī)協(xié)調(diào)多個(gè)進(jìn)程或線(xiàn)程并發(fā)訪(fǎng)問(wèn)某一資源的機(jī)制。

1.2 鎖的重要性

在數(shù)據(jù)庫(kù)中,除傳統(tǒng)計(jì)算資源(CPU、RAM、I\O等)的爭(zhēng)搶?zhuān)瑪?shù)據(jù)也是一種供多用戶(hù)共享的資源。
如何保證數(shù)據(jù)并發(fā)訪(fǎng)問(wèn)的一致性,有效性,是所有數(shù)據(jù)庫(kù)必須要解決的問(wèn)題。
鎖沖突也是影響數(shù)據(jù)庫(kù)并發(fā)訪(fǎng)問(wèn)性能的一個(gè)重要因素,因此鎖對(duì)數(shù)據(jù)庫(kù)尤其重要。

1.3 鎖的缺點(diǎn)

加鎖是消耗資源的,鎖的各種操作,包括獲得鎖、檢測(cè)鎖是否已解除、釋放鎖等 ,都會(huì)增加系統(tǒng)的開(kāi)銷(xiāo)。

1.4 簡(jiǎn)單的例子

現(xiàn)如今網(wǎng)購(gòu)已經(jīng)特別普遍了,比如淘寶雙十一活動(dòng),當(dāng)天的人流量是千萬(wàn)及億級(jí)別的,但商家的庫(kù)存是有限的。
系統(tǒng)為了保證商家的商品庫(kù)存不發(fā)生超賣(mài)現(xiàn)象,會(huì)對(duì)商品的庫(kù)存進(jìn)行鎖控制。當(dāng)有用戶(hù)正在下單某款商品最后一件時(shí),
系統(tǒng)會(huì)立馬對(duì)該件商品進(jìn)行鎖定,防止其他用戶(hù)也重復(fù)下單,直到支付動(dòng)作完成才會(huì)釋放(支付成功則立即減庫(kù)存售罄,支付失敗則立即釋放)。

鎖的類(lèi)型

2.1 表鎖

種類(lèi)

讀鎖(read lock),也叫共享鎖(shared lock)
針對(duì)同一份數(shù)據(jù),多個(gè)讀操作可以同時(shí)進(jìn)行而不會(huì)互相影響(select)
寫(xiě)鎖(write lock),也叫排他鎖(exclusive lock)
當(dāng)前操作沒(méi)完成之前,會(huì)阻塞其它讀和寫(xiě)操作(update、insert、delete)

存儲(chǔ)引擎默認(rèn)鎖

MyISAM

特點(diǎn)

1. 對(duì)整張表加鎖
2. 開(kāi)銷(xiāo)小
3. 加鎖快
4. 無(wú)死鎖
5. 鎖粒度大,發(fā)生鎖沖突概率大,并發(fā)性低
結(jié)論
1. 讀鎖會(huì)阻塞寫(xiě)操作,不會(huì)阻塞讀操作
2. 寫(xiě)鎖會(huì)阻塞讀和寫(xiě)操作
建議
MyISAM的讀寫(xiě)鎖調(diào)度是寫(xiě)優(yōu)先,這也是MyISAM不適合做寫(xiě)為主表的引擎,因?yàn)閷?xiě)鎖以后,其它線(xiàn)程不能做任何操作,大量的更新使查詢(xún)很難得到鎖,從而造成永遠(yuǎn)阻塞。

2.2 行鎖

種類(lèi)

讀鎖(read lock),也叫共享鎖(shared lock)
允許一個(gè)事務(wù)去讀一行,阻止其他事務(wù)獲得相同數(shù)據(jù)集的排他鎖
寫(xiě)鎖(write lock),也叫排他鎖(exclusive lock)
允許獲得排他鎖的事務(wù)更新數(shù)據(jù),阻止其他事務(wù)取得相同數(shù)據(jù)集的共享鎖和排他鎖
意向共享鎖(IS)
一個(gè)事務(wù)給一個(gè)數(shù)據(jù)行加共享鎖時(shí),必須先獲得表的IS鎖
意向排它鎖(IX)
一個(gè)事務(wù)給一個(gè)數(shù)據(jù)行加排他鎖時(shí),必須先獲得該表的IX鎖
存儲(chǔ)引擎默認(rèn)鎖
InnoDB
特點(diǎn)
1. 對(duì)一行數(shù)據(jù)加鎖
2. 開(kāi)銷(xiāo)大
3. 加鎖慢
4. 會(huì)出現(xiàn)死鎖
5. 鎖粒度小,發(fā)生鎖沖突概率最低,并發(fā)性高
事務(wù)并發(fā)帶來(lái)的問(wèn)題
1. 更新丟失
解決:讓事務(wù)變成串行操作,而不是并發(fā)的操作,即對(duì)每個(gè)事務(wù)開(kāi)始---對(duì)讀取記錄加排他鎖
2. 臟讀
解決:隔離級(jí)別為Read uncommitted
3. 不可重讀
解決:使用Next-Key Lock算法來(lái)避免
4. 幻讀
解決:間隙鎖(Gap Lock)

2.3 頁(yè)鎖

開(kāi)銷(xiāo)、加鎖時(shí)間和鎖粒度介于表鎖和行鎖之間,會(huì)出現(xiàn)死鎖,并發(fā)處理能力一般(此鎖不做多介紹)

如何上鎖?

3.1 表鎖

隱式上鎖(默認(rèn),自動(dòng)加鎖自動(dòng)釋放)
select //上讀鎖
insert、update、delete //上寫(xiě)鎖
顯式上鎖(手動(dòng))
lock table tableName read;//讀鎖
lock table tableName write;//寫(xiě)鎖
解鎖(手動(dòng))
unlock tables;//所有鎖表
session01session02
lock table teacher read;//上讀鎖
select * from teacher;  //可以正常讀取select * from teacher;//可以正常讀取
update teacher set name = 3 where id =2;//報(bào)錯(cuò)因被上讀鎖不能寫(xiě)操作update teacher set name = 3 where id =2;//被阻塞
unlock tables;//解鎖

update teacher set name = 3 where id =2;//更新操作成功
session01session02
lock table teacher write;//上寫(xiě)鎖
select * from teacher;  //可以正常讀取select * from teacher;//被阻塞
update teacher set name = 3 where id =2;//可以正常更新操作update teacher set name = 4 where id =2;//被阻塞
unlock tables;//解鎖

select * from teacher;//讀取成功

update teacher set name = 4 where id =2;//更新操作成功

3.2 行鎖

隱式上鎖(默認(rèn),自動(dòng)加鎖自動(dòng)釋放)

select //不會(huì)上鎖
insert、update、delete //上寫(xiě)鎖
顯式上鎖(手動(dòng))
select * from tableName lock in share mode;//讀鎖
select * from tableName for update;//寫(xiě)鎖
解鎖(手動(dòng))
1. 提交事務(wù)(commit)
2. 回滾事務(wù)(rollback)
3. kill 阻塞進(jìn)程
session01session02
begin;
select * from teacher where id = 2 lock in share mode;//上讀鎖

select * from teacher where id = 2;//可以正常讀取
update teacher set name = 3 where id =2;// 可以更新操作update teacher set name = 5 where id =2;//被阻塞
commit;

update teacher set name = 5 where id =2;//更新操作成功
session01session02
begin;
select * from teacher where id = 2 for update;//上寫(xiě)鎖

select * from teacher where id = 2;//可以正常讀取
update teacher set name = 3 where id =2;// 可以更新操作update teacher set name = 5 where id =2;//被阻塞
rollback;

update teacher set name = 5 where id =2;//更新操作成功
為什么上了寫(xiě)鎖,別的事務(wù)還可以讀操作?
因?yàn)镮nnoDB有MVCC機(jī)制(多版本并發(fā)控制),可以使用快照讀,而不會(huì)被阻塞。

行鎖的實(shí)現(xiàn)算法

4.1 Record Lock鎖

單個(gè)行記錄上的鎖
Record Lock總是會(huì)去鎖住索引記錄,如果InnoDB存儲(chǔ)引擎表建立的時(shí)候沒(méi)有設(shè)置任何一個(gè)索引,這時(shí)InnoDB存儲(chǔ)引擎會(huì)使用隱式的主鍵來(lái)進(jìn)行鎖定

4.2 Gap Lock鎖

當(dāng)我們用范圍條件而不是相等條件檢索數(shù)據(jù),并請(qǐng)求共享或排他鎖時(shí),InnoDB會(huì)給符合條件的已有數(shù)據(jù)記錄的索引加鎖,對(duì)于鍵值在條件范圍內(nèi)但并不存在的記錄。

優(yōu)點(diǎn):解決了事務(wù)并發(fā)的幻讀問(wèn)題
不足:因?yàn)閝uery執(zhí)行過(guò)程中通過(guò)范圍查找的話(huà),他會(huì)鎖定爭(zhēng)個(gè)范圍內(nèi)所有的索引鍵值,即使這個(gè)鍵值并不存在。
間隙鎖有一個(gè)致命的弱點(diǎn),就是當(dāng)鎖定一個(gè)范圍鍵值之后,即使某些不存在的鍵值也會(huì)被無(wú)辜的鎖定,而造成鎖定的時(shí)候無(wú)法插入鎖定鍵值范圍內(nèi)任何數(shù)據(jù)。在某些場(chǎng)景下這可能會(huì)對(duì)性能造成很大的危害。

4.3 Next-key Lock鎖

同時(shí)鎖住數(shù)據(jù)+間隙鎖
在Repeatable Read隔離級(jí)別下,Next-key Lock 算法是默認(rèn)的行記錄鎖定算法。

4.4 行鎖的注意點(diǎn)

1. 只有通過(guò)索引條件檢索數(shù)據(jù)時(shí),InnoDB才會(huì)使用行級(jí)鎖,否則會(huì)使用表級(jí)鎖(索引失效,行鎖變表鎖)
2. 即使是訪(fǎng)問(wèn)不同行的記錄,如果使用的是相同的索引鍵,會(huì)發(fā)生鎖沖突
3. 如果數(shù)據(jù)表建有多個(gè)索引時(shí),可以通過(guò)不同的索引鎖定不同的行

如何排查鎖?

5.1 表鎖

查看表鎖情況
show open tables;

MySQL鎖機(jī)制的示例分析

表鎖分析
show status like 'table%';

MySQL鎖機(jī)制的示例分析

1. table_locks_waited
出現(xiàn)表級(jí)鎖定爭(zhēng)用而發(fā)生等待的次數(shù)(不能立即獲取鎖的次數(shù),每等待一次值加1),此值高說(shuō)明存在著較嚴(yán)重的表級(jí)鎖爭(zhēng)用情況
2. table_locks_immediate
產(chǎn)生表級(jí)鎖定次數(shù),不是可以立即獲取鎖的查詢(xún)次數(shù),每立即獲取鎖加1

5.2 行鎖

行鎖分析

show status like 'innodb_row_lock%';

MySQL鎖機(jī)制的示例分析

1. innodb_row_lock_current_waits //當(dāng)前正在等待鎖定的數(shù)量
2. innodb_row_lock_time //從系統(tǒng)啟動(dòng)到現(xiàn)在鎖定總時(shí)間長(zhǎng)度
3. innodb_row_lock_time_avg //每次等待所花平均時(shí)間
4. innodb_row_lock_time_max //從系統(tǒng)啟動(dòng)到現(xiàn)在等待最長(zhǎng)的一次所花時(shí)間
5. innodb_row_lock_waits //系統(tǒng)啟動(dòng)后到現(xiàn)在總共等待的次數(shù)
information_schema庫(kù)
1. innodb_lock_waits表
2. innodb_locks表
3. innodb_trx表
優(yōu)化建議
1. 盡可能讓所有數(shù)據(jù)檢索都通過(guò)索引來(lái)完成,避免無(wú)索引行鎖升級(jí)為表鎖
2. 合理設(shè)計(jì)索引,盡量縮小鎖的范圍
3. 盡可能較少檢索條件,避免間隙鎖
4. 盡量控制事務(wù)大小,減少鎖定資源量和時(shí)間長(zhǎng)度
5. 盡可能低級(jí)別事務(wù)隔離

死鎖

6.1 解釋

指兩個(gè)或者多個(gè)事務(wù)在同一資源上相互占用,并請(qǐng)求鎖定對(duì)方占用的資源,從而導(dǎo)致惡性循環(huán)的現(xiàn)象

6.2 產(chǎn)生的條件

1. 互斥條件:一個(gè)資源每次只能被一個(gè)進(jìn)程使用
2. 請(qǐng)求與保持條件:一個(gè)進(jìn)程因請(qǐng)求資源而阻塞時(shí),對(duì)已獲得的資源保持不放
3. 不剝奪條件:進(jìn)程已獲得的資源,在沒(méi)有使用完之前,不能強(qiáng)行剝奪
4. 循環(huán)等待條件:多個(gè)進(jìn)程之間形成的一種互相循環(huán)等待的資源的關(guān)系

6.1 解決

1. 查看死鎖:show engine innodb status \G
2. 自動(dòng)檢測(cè)機(jī)制,超時(shí)自動(dòng)回滾代價(jià)較小的事務(wù)(innodb_lock_wait_timeout 默認(rèn)50s)
3. 人為解決,kill阻塞進(jìn)程(show processlist)
4. wait for graph 等待圖(主動(dòng)檢測(cè))

6.1 如何避免

1. 加鎖順序一致,盡可能一次性鎖定所需的數(shù)據(jù)行
2. 盡量基于primary(主鍵)或unique key更新數(shù)據(jù)
3. 單次操作數(shù)據(jù)量不宜過(guò)多,涉及表盡量少
4. 減少表上索引,減少鎖定資源
5. 盡量使用較低的隔離級(jí)別
6. 盡量使用相同條件訪(fǎng)問(wèn)數(shù)據(jù),這樣可以避免間隙鎖對(duì)并發(fā)的插入影響
7. 精心設(shè)計(jì)索引,盡量使用索引訪(fǎng)問(wèn)數(shù)據(jù)
8. 借助相關(guān)工具:pt-deadlock-logger

樂(lè)觀(guān)鎖與悲觀(guān)鎖

MySQL鎖機(jī)制的示例分析

7.1 悲觀(guān)鎖

解釋
假定會(huì)發(fā)生并發(fā)沖突,屏蔽一切可能違反數(shù)據(jù)完整性的操作
實(shí)現(xiàn)機(jī)制
表鎖、行鎖等
實(shí)現(xiàn)層面
數(shù)據(jù)庫(kù)本身
適用場(chǎng)景
并發(fā)量大

7.2 樂(lè)觀(guān)鎖

解釋
假設(shè)不會(huì)發(fā)生并發(fā)沖突,只在提交操作時(shí)檢查是否違反數(shù)據(jù)完整性
實(shí)現(xiàn)機(jī)制
提交更新時(shí)檢查版本號(hào)或者時(shí)間戳是否符合
實(shí)現(xiàn)層面
業(yè)務(wù)代碼
適用場(chǎng)景
并發(fā)量小

感謝你能夠認(rèn)真閱讀完這篇文章,希望小編分享的“MySQL鎖機(jī)制的示例分析”這篇文章對(duì)大家有幫助,同時(shí)也希望大家多多支持創(chuàng)新互聯(lián),關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,更多相關(guān)知識(shí)等著你來(lái)學(xué)習(xí)!


網(wǎng)站題目:MySQL鎖機(jī)制的示例分析
文章分享:http://weahome.cn/article/ijssis.html

其他資訊

在線(xiàn)咨詢(xún)

微信咨詢(xún)

電話(huà)咨詢(xún)

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部