一区二区三区三上|欧美在线视频五区|国产午夜无码在线观看视频|亚洲国产裸体网站|无码成年人影视|亚洲AV亚洲AV|成人开心激情五月|欧美性爱内射视频|超碰人人干人人上|一区二区无码三区亚洲人区久久精品

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

一文徹底搞懂MySQL鎖究竟鎖的啥1

jf_78858299 ? 來源:蟬沐風(fēng)的碼場(chǎng) ? 作者:蟬沐風(fēng) ? 2023-03-03 10:12 ? 次閱讀

MySQL鎖系列文章已經(jīng)鴿了挺久了,最近趕緊擠了擠時(shí)間,和大家聊一聊MySQL的鎖。

只要學(xué)計(jì)算機(jī),「」永遠(yuǎn)是一個(gè)繞不過的話題。MySQL鎖也是一樣。

一句話解釋MySQL鎖:

MySQL鎖是解決資源競(jìng)爭(zhēng)的一種方案。

短短一句話卻包含了3點(diǎn)值得我們注意的事情:

  1. 對(duì)什么資源進(jìn)行競(jìng)爭(zhēng)?
  2. 競(jìng)爭(zhēng)的方式(或者說情形)有哪些?
  3. 鎖是如何解決競(jìng)爭(zhēng)的?

這篇文章開始帶你循序漸進(jìn)地理解這幾個(gè)問題。

1. 資源的競(jìng)爭(zhēng)方式

MySQL對(duì)資源的操作無非就是 、兩種方式,但是由于事務(wù)并發(fā)執(zhí)行的存在,因此對(duì)同一資源的并發(fā)訪問存在3種形式:

  • 讀—讀:并發(fā)事務(wù)同時(shí)讀取相同資源。由于讀操作不會(huì)改變資源本身,因此 這種情況下并不存在并發(fā)安全性問題 。
  • 讀—寫/寫—讀:一個(gè)事務(wù)對(duì)資源進(jìn)行讀操作,另一個(gè)事務(wù)對(duì)資源進(jìn)行寫操作。
  • 寫—寫:并發(fā)事務(wù)同時(shí)對(duì)同一個(gè)資源進(jìn)行寫操作。

2. 讀—寫/寫—讀下的問題

假設(shè)一種情形,一個(gè)事務(wù)先對(duì)某個(gè)資源進(jìn)行讀操作,然后另一個(gè)事務(wù)再對(duì)該資源進(jìn)行寫操作,如果兩個(gè)事務(wù)到此為止,必然不會(huì)導(dǎo)致并發(fā)問題。

可是事務(wù)這種東西,一般情況下就是包含有很多個(gè)子操作啊。

2.1. 幻讀

想象一下啊,假設(shè)事務(wù)T1T2并發(fā)執(zhí)行,T1先查找了所有name為「王剛蛋」的用戶信息,此時(shí)發(fā)現(xiàn)擁有這個(gè)硬漢名字的用戶只有一個(gè)。然后T2插入了一個(gè)同樣叫做「王剛蛋」的用戶的信息,并且提交了。

圖片

幻讀

圖片

2.2. 不可重復(fù)讀

再來,同樣是T1T2兩個(gè)事務(wù),T1通過id = 1查詢到了一條數(shù)據(jù),然后T2緊接著UPDATEDELETE也可以)了該條記錄,不同的是,T2緊接著通過COMMIT提交了事務(wù)。

圖片

此時(shí),T1再次執(zhí)行相同的查詢操作,會(huì)發(fā)現(xiàn)數(shù)據(jù)發(fā)生了變化,name字段由「王剛蛋」變成了「蟬沐風(fēng)」。

如果一個(gè)事務(wù)讀到了另一個(gè)已提交事務(wù)修改過的(或者是刪除的)數(shù)據(jù),而導(dǎo)致了前后兩次讀取的數(shù)據(jù)不一致的情況,這種事務(wù)并發(fā)問題叫做 不可重復(fù)讀 。

2.3. 臟讀

事情還沒結(jié)束,假設(shè)T1T2都要訪問user_innodb表中id1的數(shù)據(jù),不同的是T1先讀取數(shù)據(jù),緊接著T2修改了數(shù)據(jù)的name字段,需要注意的是,T2并沒有提交!

圖片

此時(shí),T1再次執(zhí)行相同的查詢操作,會(huì)發(fā)現(xiàn)數(shù)據(jù)發(fā)生了變化,name字段由「王剛蛋」變成了「蟬沐風(fēng)」。

如果一個(gè)事務(wù)讀到了另一個(gè)未提交事務(wù)修改過的數(shù)據(jù),而導(dǎo)致了前后兩次讀取的數(shù)據(jù)不一致的情況,這種事務(wù)并發(fā)問題叫做 臟讀 。

2.4. 鎖與MVCC的關(guān)系

總結(jié)一下:我們?cè)谧x—寫,寫—讀的情況下會(huì)遇到3種讀不一致性的問題,臟讀、不可重復(fù)讀以及幻讀。

那寫—寫呢?很顯然,在不做任何措施的情況下,并發(fā)會(huì)出現(xiàn)更大的問題。那該怎么辦呢?

一切的并發(fā)問題都可以通過串行化解決,但是串行化效率太低了!

再優(yōu)化一下,一切并發(fā)問題都可以通過加鎖來解決,這種方案我們稱為 基于鎖的并發(fā)控制Lock Bases Concurrency Control , LBCC )!但是在讀多寫少的環(huán)境下,客戶端連讀取幾條記錄都需要排隊(duì),效率還是太低了!

因此,MySQL的設(shè)計(jì)者為事務(wù)之間的隔離性提供了不同的級(jí)別,使得開發(fā)者可以根據(jù)自己的業(yè)務(wù)場(chǎng)景設(shè)置不同的隔離級(jí)別,來解決(或者部分解決)讀—寫/寫—讀下的讀一致性問題,而不是一上來就加鎖。

這種機(jī)制叫做MVCC,如果你對(duì)這個(gè)概念不是很了解,我建議你暫停一下,讀一下我的事務(wù)的隔離性與MVCC這篇文章,寫得賊好!?。ㄗ再u自夸一下)

那有了MVCC是不是在讀—寫/寫—讀的情況下就不需要鎖了呢?那也不是。

MVCC解決的是讀—寫/寫—讀中“ 比較純粹的讀 ”遇到的一致性問題,原諒我,這是我自己編的詞兒。那什么是不純粹的?拿存款業(yè)務(wù)舉個(gè)例子。

假設(shè)陀螺要存一筆錢,系統(tǒng)需要先把陀螺的余額讀出來,然后在余額的基礎(chǔ)上加上本次存款的金額,最后再寫入到數(shù)據(jù)庫(kù)中。在將余額讀出來之后,如果不想讓其他事務(wù)繼續(xù)訪問該余額,直到整個(gè)存款事務(wù)完成之后,其他事務(wù)才可以對(duì)該余額繼續(xù)進(jìn)行操作,這種情況下就必須為余額的讀取操作添加鎖。

再總結(jié)一下: MVCC是MySQL默認(rèn)的解決讀—寫/寫—讀下一致性問題的方式,不需要加鎖。而鎖是實(shí)現(xiàn)一致性的最終兜底方案,在某些特殊場(chǎng)景下,鎖的使用不可避免 。

說得更準(zhǔn)確一點(diǎn),MVCC是MySQL在READ COMMITTED、REPEATABLE READ這兩種隔離級(jí)別之下執(zhí)行普通SELECT操作時(shí)默認(rèn)解決一致性問題的方式。

具體為什么只是這兩種隔離級(jí)別,建議你看看事務(wù)的隔離性與MVCC。

2.5. 鎖與事務(wù)的關(guān)系

事務(wù)是多個(gè)操作的集合,比如我們可以把「把大象裝冰箱」這件事情作為一個(gè)事務(wù)。

圖片

事務(wù)有A(原子性)、C(一致性)、I(隔離性)、D(持久性)4大特性,而鎖就是實(shí)現(xiàn)隔離性的其中一種方案(比如還有MVCC等方案)。

事務(wù)的隔離性針對(duì)不同場(chǎng)景需求又實(shí)現(xiàn)了不同的隔離級(jí)別,不同的隔離級(jí)別下,事務(wù)使用鎖的方式又會(huì)有所不同。舉個(gè)例子。

READ COMMITTED、REPEATABLE READ這兩種隔離級(jí)別之下,SELECT操作是不需要加鎖的,直接使用MVCC機(jī)制即可滿足當(dāng)前隔離級(jí)別的需求。但是在SERIALIZABLE隔離級(jí)別,并且在禁用自動(dòng)提交時(shí)(autocommit=0),MySQL會(huì)將普通的SELECT語句轉(zhuǎn)化為SELECT ... LOCK IN SHARE MODE這樣的加鎖語句,如果你看不懂這句話也沒關(guān)系,你只需要知道MySQL自動(dòng)加鎖了就行,更詳細(xì)的下文再說。

另外,一個(gè)事務(wù)可能會(huì)加很多個(gè)鎖,但是某個(gè)鎖一定只屬于一個(gè)事務(wù)。這就好比一個(gè)管理員可以管理多個(gè)保險(xiǎn)柜,一個(gè)保險(xiǎn)柜一定只被一個(gè)管理員管理。

3. 寫—寫情況

寫—寫的情況下肯定要加鎖的了,所以接下來終于要聊一聊鎖了。

我們首先研究一下鎖住的東西的大小,也就是鎖的粒度。

4. 鎖的粒度

舉一個(gè)非常應(yīng)景的例子。疫情防控的時(shí)候,是封鎖整個(gè)小區(qū)還是封鎖某棟樓的某個(gè)單元,這完全是兩種概念。

對(duì)應(yīng)到MySQL鎖的粒度,那就是表鎖行鎖。

很容易想到,封鎖小區(qū)的行為遠(yuǎn)比封鎖某棟樓某單元的行為粗曠,因此,

從鎖定粒度上來看,表鎖 > 行鎖

直接堵住小區(qū)的門口要比進(jìn)入小區(qū)找到具體某棟樓的某個(gè)單元要快不少,因此,

從加鎖效率上來看,表鎖 > 行鎖

直接鎖住小區(qū)大概率會(huì)影響其他樓居民的正常生活和各種社會(huì)活動(dòng)的開展,而鎖住某棟樓某單元頂多影響這一個(gè)單元的居民的生活,因此,

從沖突概率來看,表鎖 > 行鎖

從并發(fā)性能來看,表鎖 < 行鎖

MySQL支持很多存儲(chǔ)引擎,而不同的存儲(chǔ)引擎對(duì)鎖的支持也不盡相同。對(duì)于MyISAM、MERGEMEMORY這些存儲(chǔ)引擎而言,只支持表鎖;而InnoDB存儲(chǔ)引擎既支持表鎖也支持行鎖,下文討論的所有內(nèi)容均針對(duì)InnoDB存儲(chǔ)引擎。

說完鎖的粒度,還有一件事情需要我們仔細(xì)考慮一下。上文說過,READ COMMITTED、REPEATABLE READ這兩種隔離級(jí)別之下,SELECT操作默認(rèn)采用MVCC機(jī)制就可以了,壓根兒不需要加鎖,那么問題來了,萬一我就是想加鎖呢?

你可能會(huì)說,“簡(jiǎn)單啊,那就加鎖!把數(shù)據(jù)鎖死!除了我誰也別動(dòng)!”

很好,但是對(duì)于大部分讀—讀而言,由于不會(huì)出現(xiàn)讀一致性問題,所以不讓其他事務(wù)進(jìn)行讀操作并不合理。

你可能又說,“那行吧,那就讓讀操作加鎖的時(shí)候允許其他事務(wù)對(duì)鎖住的數(shù)據(jù)進(jìn)行讀操作,但是不允許寫操作?!?/p>

嗯,想得確實(shí)更細(xì)致了一些。但是再想想我上文中舉過的陀螺存錢的例子,有時(shí)候SELECT操作需要獨(dú)占數(shù)據(jù),其他事務(wù)既不能讀,更不能寫。

我們把這種共享排他的性質(zhì)稱為鎖的基本模式。

5. 鎖的基本模式

5.1. 共享鎖

共享鎖(Shared Lock),簡(jiǎn)稱S鎖,可以同時(shí)被多個(gè)事務(wù)共享,也就是說,如果一個(gè)事務(wù)給某個(gè)數(shù)據(jù)資源添加了S鎖,其他事務(wù)也被允許獲取該數(shù)據(jù)資源的S鎖。

由于S鎖通常被用于讀取數(shù)據(jù),因此也被稱為 讀鎖

那怎么給數(shù)據(jù)添加S鎖呢?

我們可以用 SELECT ... LOCK IN SHARE MODE;的方式,在讀取數(shù)據(jù)之前就為數(shù)據(jù)添加一把S鎖。如果當(dāng)前事務(wù)執(zhí)行了該語句,那么會(huì)為讀取到的記錄添加S鎖,同時(shí)其他事務(wù)也可以使用SELECT ... LOCK IN SHARE MODE;方式繼續(xù)獲取這些數(shù)據(jù)的S鎖。

我們通過以下的例子驗(yàn)證一下S鎖是否可以重復(fù)獲取。

圖片

5.2. 排他鎖

排他鎖(Exclusive Lock),簡(jiǎn)稱X鎖。只要一個(gè)事務(wù)獲取了某數(shù)據(jù)資源的X鎖,其他的事務(wù)就不能再獲取該數(shù)據(jù)的X鎖和S鎖。

由于X鎖通常被用于修改數(shù)據(jù),因此也被稱為 寫鎖 。

X鎖的添加方式有兩種,

  1. 自動(dòng)添加X
    我們對(duì)記錄進(jìn)行增刪改時(shí),通常情況下會(huì)自動(dòng)對(duì)其添加X鎖。
  2. 手動(dòng)加鎖
    我們可以用 SELECT ... FOR UPDATE;的方式,在讀取數(shù)據(jù)之前就為數(shù)據(jù)添加一把X鎖。如果當(dāng)前事務(wù)執(zhí)行了該語句,那么會(huì)為讀取到的記錄添加X鎖,這樣既不允許其他事務(wù)獲取這些記錄的S鎖,也不允許獲取這些記錄的X鎖。

我們用下面的例子驗(yàn)證一下X鎖的排他性。

圖片

通常情況下,事務(wù)提交或結(jié)束事務(wù)時(shí),鎖會(huì)被釋放。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 計(jì)算機(jī)
    +關(guān)注

    關(guān)注

    19

    文章

    7611

    瀏覽量

    89881
  • MySQL
    +關(guān)注

    關(guān)注

    1

    文章

    841

    瀏覽量

    27369
  • MVCC
    +關(guān)注

    關(guān)注

    0

    文章

    13

    瀏覽量

    1530
收藏 人收藏

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    基于MySQL機(jī)制

    在數(shù)據(jù)庫(kù)系統(tǒng)中,為了保證數(shù)據(jù)的致性和并發(fā)控制,機(jī)制發(fā)揮著至關(guān)重要的作用。尤其在關(guān)系型數(shù)據(jù)庫(kù)MySQL中,其獨(dú)特的機(jī)制設(shè)計(jì)更是贏得了許多開發(fā)者的喜愛。 本文將詳細(xì)探討
    的頭像 發(fā)表于 09-30 11:16 ?1035次閱讀

    redis分布式場(chǎng)景實(shí)現(xiàn)

    今天帶大家深入剖析下Redis分布式,徹底搞懂它。 場(chǎng)景 既然要搞懂Redis分布式,那肯
    的頭像 發(fā)表于 09-25 17:09 ?866次閱讀

    請(qǐng)問DSPflash死后,RAM還可以用嗎,還是這塊芯片就徹底廢了?

    本帖最后由 只耳朵怪 于 2018-6-13 16:47 編輯 請(qǐng)問DSPflash死后,RAM還可以用嗎,還是這塊芯片就徹底廢了?
    發(fā)表于 06-13 04:19

    InnoDB的特點(diǎn)和狀態(tài)查詢

    MySQL探秘(五)InnoDB的類型和狀態(tài)查詢
    發(fā)表于 08-07 11:45

    讀懂eMMC究竟?

    eMMC究竟?eMMC長(zhǎng)什么樣?eMMC用在哪?主要是干嘛用的?eMMC究竟是如何工作的呢?
    發(fā)表于 06-18 06:04

    360為什么會(huì)入局智能市場(chǎng)

    很難界定智能究竟屬于哪個(gè)行業(yè)?智能是五金門鎖行業(yè)、安防行業(yè)、家居行業(yè)和產(chǎn)業(yè)互聯(lián)網(wǎng)行業(yè)的交匯產(chǎn)物。硬件是基礎(chǔ),安防及家居是應(yīng)用,網(wǎng)絡(luò)是消費(fèi)渠道及用戶交互界面,物聯(lián)網(wǎng)讓智能
    發(fā)表于 11-05 15:21 ?1550次閱讀

    詳細(xì)介紹MySQL InnoDB存儲(chǔ)引擎各種不同類型的

    T1執(zhí)行時(shí),需要獲取i=1的行的X(不需要獲取t1表的意向了);T2執(zhí)行時(shí),需要獲取t1表的
    的頭像 發(fā)表于 02-20 11:12 ?7775次閱讀
    詳細(xì)介紹<b class='flag-5'>MySQL</b> InnoDB存儲(chǔ)引擎各種不同類型的<b class='flag-5'>鎖</b>

    徹底搞懂PID到底是

    先來徹底搞懂PID到底是? PID,就是比例(proportional)、積分(integral)、微分(differential),是種很常見的控制算法。在工程實(shí)際中,應(yīng)用最為廣
    的頭像 發(fā)表于 11-13 18:21 ?2.6w次閱讀

    數(shù)據(jù)庫(kù)的機(jī)制真正的原理

    問候選人,你知道MySQL Innodb的,到底的是什么嗎?關(guān)于這個(gè)問題的回答,聽到過很多種,但是很少有人可以把他回答的很完美。因?yàn)橄胍卮鸷眠@個(gè)問題,需要對(duì)數(shù)據(jù)庫(kù)的隔離級(jí)別、索引等都有
    的頭像 發(fā)表于 11-12 09:33 ?2481次閱讀

    說說MySQL有哪些

    增加自增為 innodb_autoinc_lock_mode = 2 模式時(shí),為什么主從環(huán)境會(huì)有不安全問題的說明
    的頭像 發(fā)表于 10-24 10:15 ?994次閱讀

    MySQL是怎么加行級(jí)的?有什么規(guī)則?

    是不是很多人都對(duì) MySQL 加行級(jí)的規(guī)則搞的迷迷糊糊,對(duì)記錄會(huì)加的是 next-key ,會(huì)加是間隙
    的頭像 發(fā)表于 11-17 09:28 ?995次閱讀

    徹底搞懂MySQL究竟2

    MySQL系列文章已經(jīng)鴿了挺久了,最近趕緊擠了擠時(shí)間,和大家聊MySQL。 只要學(xué)計(jì)算機(jī),「`
    的頭像 發(fā)表于 03-03 10:13 ?548次閱讀
    <b class='flag-5'>一</b><b class='flag-5'>文</b><b class='flag-5'>徹底</b><b class='flag-5'>搞懂</b><b class='flag-5'>MySQL</b><b class='flag-5'>鎖</b><b class='flag-5'>究竟</b><b class='flag-5'>鎖</b>的<b class='flag-5'>啥</b>2

    Linux互斥的作用 互斥是什么

    1、互斥 互斥(mutex),在訪問共享資源之前對(duì)互斥進(jìn)行上鎖,在訪問完成后釋放互斥(解鎖);對(duì)互斥
    的頭像 發(fā)表于 07-21 11:13 ?1122次閱讀

    自旋和互斥的區(qū)別有哪些

    自旋 自旋與互斥很相似,在訪問共享資源之前對(duì)自旋進(jìn)行上鎖,在訪問完成后釋放自旋(解鎖);事實(shí)上,從實(shí)現(xiàn)方式上來說,互斥
    的頭像 發(fā)表于 07-21 11:19 ?9759次閱讀

    互斥和自旋的實(shí)現(xiàn)原理

    互斥和自旋是操作系統(tǒng)中常用的同步機(jī)制,用于控制對(duì)共享資源的訪問,以避免多個(gè)線程或進(jìn)程同時(shí)訪問同資源,從而引發(fā)數(shù)據(jù)不致或競(jìng)爭(zhēng)條件等問題。 互斥
    的頭像 發(fā)表于 07-10 10:07 ?865次閱讀