欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

一篇文章帶你了解清楚Mysql?鎖

 更新時間:2022年11月29日 08:36:38   作者:Cuzzz  
這篇文章主要介紹了一篇文章帶你了解清楚Mysql?鎖的相關(guān)資料,需要的朋友可以參考下

一丶為什么數(shù)據(jù)庫需要鎖

數(shù)據(jù)庫鎖設(shè)計的初衷是處理并發(fā)問題。作為多用戶共享 的資源,當(dāng)出現(xiàn)并發(fā)訪問的時候,數(shù)據(jù)庫需要合理地控制資源的訪問規(guī)則。而鎖就是用來實 現(xiàn)這些訪問規(guī)則的重要數(shù)據(jù)結(jié)構(gòu)。

根據(jù)加鎖的范圍,MySQL 里面的鎖大致可以分成全局鎖、表級鎖行鎖三類

二丶全局鎖&全庫邏輯備份

全局鎖就是對整個數(shù)據(jù)庫實例加鎖。全局鎖的典型使用場景是,做全庫邏輯備份,全庫邏輯備份有以下幾種方式:

1.Flush tables with read lock (FTWRL)

Flush tables with read lock (FTWRL)可以讓整個庫處于只讀狀態(tài)的時候,使用這個命令,之后其他線程的數(shù)據(jù)更新語句(數(shù)據(jù)的增刪改)、數(shù)據(jù)定義語句(包括建表、修改表結(jié)構(gòu)等)和更新類事務(wù)的提交語句講被阻塞。之所以備份需要加全局鎖是為了保證數(shù)據(jù)的一致性,

2.mysqldump –single-transaction

使用此命令會先啟動一個事務(wù)拿到一致性視圖。由于 MVCC 的支持, 這個過程中其他線程可以進(jìn)行正常操作,但是使用mysqldump –single-transaction的前提是需要支持事務(wù),如果存在MyISAM引擎的表,并不能保證一致性。

3.set global readonly=true

set global readonly=true也可以保證全庫只讀,主要有兩個原因:

在有些系統(tǒng)中,readonly 的值會被用來做其他邏輯,比如用來判斷一個庫是主庫還是備庫。因此,修改 global 變量的方式影響面更大。 在異常處理機制上有差異。如果執(zhí)行 FTWRL 命令之后由于客戶端發(fā)生異常斷開, 那么 MySQL 會自動釋放這個全局鎖,整個庫回到可以正常更新的狀態(tài)。而將整個庫設(shè)置為 readonly 之后,如果客戶端發(fā)生異常,則數(shù)據(jù)庫就會一直保持 readonly 狀態(tài),這樣會導(dǎo)致整個庫長時間處于不可寫狀態(tài),風(fēng)險較高。

三丶鎖解決并發(fā)事務(wù)帶來的問題

1.鎖解決臟寫

多個未提交事務(wù)修改相繼對同一條記錄進(jìn)行改動的時候,需要進(jìn)行排隊,排隊過程其實就是通過為記錄加鎖實現(xiàn)的。當(dāng)一個事務(wù)想修改記錄的時候,首先需要看下有沒有于記錄相關(guān)聯(lián)的鎖結(jié)構(gòu),如果沒有,那么會在內(nèi)存中生成與之對應(yīng)的鎖結(jié)構(gòu)

可能多個事務(wù)同時修改同一記錄,會產(chǎn)生多個鎖結(jié)構(gòu),其中只有一個事務(wù)可以獲取到鎖,其is_waiting為false,其他事務(wù)is_waiting為true,當(dāng)獲取鎖的事務(wù)結(jié)束后,會喚醒其他等待的事務(wù)

2.臟讀,幻讀,不可重復(fù)讀如何避免

mysql innodb 在repeatable隔離級別下很大程度下避免了幻讀(后續(xù)詳細(xì)說到)

2.1 mvcc解決臟讀,幻讀,不可重復(fù)讀問題

Mysql InnoDB多版本并發(fā)控制MVCC 這篇博客我們詳細(xì)說到了mvcc的實現(xiàn)的原理,簡單來說就是在事務(wù)運行時會生成read view,其包含四個部分

  • m_ids:在生成read view時,當(dāng)前系統(tǒng)中活躍的讀寫事務(wù)id列表
  • min_trx_id:生成read view時,當(dāng)前系統(tǒng)中活躍的讀寫事務(wù)中最小事務(wù)id,也就是m_ids中的最小值
  • max_trx_id:生成read view時,系統(tǒng)應(yīng)該分配給下一個事務(wù)的事務(wù)id值
  • creator_trx_id:生成該read view的事務(wù)的事務(wù)id

查詢語句只可以查詢生成read view 時刻可以看到的數(shù)據(jù),及事務(wù)id小于min_trx_id中的數(shù)據(jù),寫操作則針對最新的數(shù)據(jù)。非當(dāng)前讀的普通語句在讀數(shù)據(jù)的時候,生成read view的時機不同,在可重復(fù)讀的時候只會在第一次讀取(如果使用start transaction with consistent snapshot則是在事務(wù)啟動時)生成一個read view 后續(xù)不變,達(dá)到可重復(fù)讀的目的,對于讀已提交,則是每次讀取都會生成新的read view,從刷新未提交事務(wù)集合,和min_trx_id,讀取到已經(jīng)提交的數(shù)據(jù)。使用mvcc讓讀寫并不沖突,數(shù)據(jù)庫的并發(fā)能力更強。

2.2讀寫均加鎖

比如在銀行存款業(yè)務(wù)中,我們需要先讀取賬戶余額,然后加上新增存款,然后進(jìn)行寫回操作,整個流程中,我們不希望存在另外一個ATM進(jìn)行存取的操作,讀寫都需要排隊,這時候就得使用鎖。

上面我們說了,寫操作進(jìn)行排隊可以解決臟寫,那么臟讀,不可重復(fù)讀,幻讀是怎么使用讀寫加鎖解決昵?

臟讀產(chǎn)生的原因是,當(dāng)前事務(wù)讀取到了另外一個事務(wù)沒有提交的數(shù)據(jù),那么只需要另外一個事務(wù)對操作的記錄加鎖,當(dāng)前事務(wù)無法獲取到鎖,自然就不會發(fā)生臟讀。

不可重復(fù)讀產(chǎn)生的原因是,當(dāng)前事務(wù)先讀取了一條記錄,然后存在另外一個事務(wù)修改了此記錄的數(shù)據(jù),那么只要當(dāng)前事務(wù)對記錄進(jìn)行加鎖,自然后續(xù)的事務(wù)將無法修改,自然不會發(fā)生不可重復(fù)讀。

幻讀產(chǎn)生的原因是,當(dāng)前事務(wù)根據(jù)條件查詢得到一批數(shù)據(jù),然后后續(xù)事務(wù)新增了滿足這些條件的數(shù)據(jù),導(dǎo)致再次查詢時發(fā)現(xiàn)多了一些數(shù)據(jù),如同出現(xiàn)了幻覺。這里加鎖則不是單對記錄加鎖,而是要鎖住一個范圍,讓其他事務(wù)無法插入數(shù)據(jù),從而解決幻讀(后續(xù)會說到這種鎖)

很明顯讀寫都加鎖,并發(fā)能力不及mvcc

3.一致性讀

事務(wù)利用MVCC進(jìn)行讀取操作稱為一致性讀(又稱一致性無鎖讀,快照讀),基本上所有的普通讀在可重復(fù)讀,讀提交隔離級別下,都是一致性讀。

4.鎖定讀

4.1共享鎖&獨占鎖

共享鎖:簡稱S鎖,事務(wù)要讀取一條記錄的時候需要先獲取到記錄的共享鎖

獨占鎖:簡稱x鎖,當(dāng)事務(wù)需要改動記錄的時候,需要先獲取記錄的獨占鎖

共享鎖和共享鎖兼容,獨占鎖和獨占鎖,獨占鎖和共享鎖互斥

4.2鎖定讀的語句

select xxx lock in share mode可以對讀取的記錄加S鎖

select xxx for update可以對讀取的記錄加X鎖

4.3 寫操作

delete

刪除記錄首先要在b+數(shù)中定位到這條記錄的位置,然后獲取x鎖,然后指向delete mark(標(biāo)記記錄被刪除)

update

如果未修改鍵值,并且修改前后數(shù)據(jù)的存儲空間大小不變,那么現(xiàn)在b+樹上定位記錄,然后加x鎖。反之需要在b+樹上定位數(shù)據(jù),然后把記錄徹底刪除嗎,然后再插入一條新的記錄,對新增的這條數(shù)據(jù)加x鎖

insert

新插入記錄一般都是加隱式鎖(后面說)不需要在內(nèi)存中生成對應(yīng)的鎖結(jié)構(gòu)。

三丶InnoDB表鎖

1.表級S,X鎖

innodb支持表級鎖,也支持行級鎖,表級鎖粒度相對更粗,占用資源較少。使用表級鎖效果相當(dāng)于為表中的所有記錄加鎖,所以性能比較差。

表級S鎖,X鎖

使用Lock Tables t Read,innodb存儲引擎會對表t加共享鎖

使用Lock tables t write,innodb存儲引擎會對表t加獨占鎖

類似于Java中的讀寫鎖,共享鎖和共享鎖不互斥,獨占鎖和獨占鎖,獨占鎖和共享鎖互斥。

2.表級意向鎖

innodb存儲引擎中,當(dāng)對表中某些記錄加S鎖之前,會在表上加上一個IS鎖,同樣加X鎖之前會加表級IX鎖,這里的I表示意向鎖,SX表示共享還是互斥,表級意向鎖存在的目的是后續(xù)對表加S鎖,X鎖的時候,可以快速判斷表中是否存在加鎖的記錄,避免遍歷每一個記錄查看是否被加鎖。

3.表級AUTO-INC鎖

mysql可以為某列執(zhí)行Auto Increment自增,系統(tǒng)給自增列賦值的實現(xiàn)方式主要存在兩種

使用AUTO-INC鎖,執(zhí)行插入語句的時候加一個表級AUTO-INC鎖,然后為每條待插入的記錄中的自增列,進(jìn)行遞增賦值,單個插入語句執(zhí)行結(jié)束后釋放AUTO-INC鎖。這樣會導(dǎo)致其他事務(wù)的插入被阻塞。 采用輕量級AUTO-INC鎖,在為插入列賦值結(jié)束后,就釋放輕量級鎖,而不是插入語句執(zhí)行完后才釋放 四.MDL

一般情況下 對某一個表執(zhí)行增刪改查的時候,都不會加表鎖,但是執(zhí)行一些DDL修改表結(jié)構(gòu),刪除表時,其他事務(wù)對這表的增刪改查發(fā)生阻塞。這是由MDL鎖實現(xiàn)的,MDL鎖也分為讀鎖和寫鎖,在進(jìn)行crud操作的時候,會加MDL讀鎖,進(jìn)行DDL的時候會加MDL寫鎖。

我們需要注意MDL讀鎖寫鎖是互斥的

如圖四個不同的session先后依次執(zhí)行語句,其中A,B都是獲取MDL讀鎖,互不阻塞,隨即C獲取MDL寫鎖,這時候C會被阻塞,這一阻塞不打緊,還會阻塞后續(xù)獲取MDL讀鎖的事務(wù),造成整個表不可用。這啟發(fā)了我們,在做DDL的時候要解決長事務(wù),事務(wù)不提交,就會一直占著MDL鎖。在 MySQL 的 information_schema 庫的innodb_trx 表中,可以查到當(dāng)前執(zhí)行中的事務(wù)。如果要做 DDL 變更的表剛好有長事務(wù)在執(zhí)行,要考慮先暫停 DDL,或者 kill 掉這個長事務(wù)。

五丶innodb 行鎖

1.Record Lock

官方名稱Lock_REC_NOT_GAP

記錄鎖有S鎖和X鎖,S型記錄鎖之間可以共享,X型記錄鎖和S型記錄鎖,X型記錄鎖互斥

2.GAP Lock

innodb的可重復(fù)讀級別,使用詞鎖解決幻讀問題,前面我們說過,其難點在于,加鎖的時候幻影記錄還未出現(xiàn)。官方使用Lock_GAP實現(xiàn)如下操作

此處的gap鎖可以反之其他事務(wù)在number為8記錄前面的間隙插入新的記錄,在區(qū)間(3,8)內(nèi)無法進(jìn)行插入操作,當(dāng)另外一個事務(wù)要插入number為4的記錄時,首先需要定位到該條記錄的下一條記錄,也就是number為8的記錄,此時number為8的記錄具備gap鎖,所以將阻塞插入操作,直到gap鎖被釋放,其他事務(wù)才能進(jìn)行插入。
gap鎖出現(xiàn)的目的,就是為了防止插入幻影記錄,如果對記錄上gap鎖,并不會限制其他事務(wù)對記錄加記錄鎖。

innodb有兩個虛擬的記錄Infimum(虛擬最小),Supermun(虛擬最大)當(dāng)我們想在(xx,正無窮)范圍鎖住幻影記錄時就可以對Supermun加gap鎖。

3.Next-Key Lock

Next-Key Lock = 記錄鎖 + gap鎖,既鎖住記錄,也鎖住記錄之前的間隙

4.Insert Intention Lock

插入意向鎖,表示事務(wù)想在某個間隙插入新的記錄,但是當(dāng)前處于等待狀態(tài)。

比如事務(wù)A持有(4,8)范圍內(nèi)的gap鎖,事務(wù)B和C,想插入(4,8)范圍內(nèi)的記錄,就會在內(nèi)存中生成事務(wù)B,C對應(yīng)的插入意向鎖,當(dāng)前事務(wù)A釋放gap鎖的時候,將喚醒事務(wù)B和C,事務(wù)B和C可以同時獲取插入意向鎖,然后進(jìn)行插入。插入意向鎖并不會阻止對記錄繼續(xù)上鎖。

5.隱式鎖

為事務(wù)生成內(nèi)存中的鎖結(jié)構(gòu)并不是一個0成本的事情,為了節(jié)省這個成本,提出隱式鎖的概念。

當(dāng)一個事務(wù)插入語一條記錄A,其他事務(wù)

select xxx Lock in share mode讀取記錄A(獲取記錄A的S鎖),或者使用select xxx for update(獲取記錄A的X鎖) 立即修改記錄A(獲取x鎖)

對于聚簇索引來說,有一個隱藏列trx_id此列存儲著最后更改記錄的事務(wù)id,在當(dāng)前事務(wù)A插入記錄后,便是存儲著當(dāng)前事務(wù)A的id,其他事務(wù)B企圖獲取x鎖,s鎖的時候,就需要下先看一下,trx_id隱藏列對應(yīng)的事務(wù)是否存活,如果不是那么正常獲取,反之需要為當(dāng)前事務(wù)A創(chuàng)建一個x鎖內(nèi)存結(jié)構(gòu),并標(biāo)記is_waiting為false,然后事務(wù)B將為自己創(chuàng)建一個鎖結(jié)構(gòu),is_waiting 為true然后事務(wù)B進(jìn)入等待狀態(tài)

對于二級索引來說,其不具備隱藏列trx_id但是在二級索引頁面的page header中的page_maxt_trx_id屬性,記錄了改動頁面最大的事務(wù)id,如果其屬性值小于當(dāng)前最小的活躍事務(wù)id,那么說明對頁面的改動事務(wù)已經(jīng)提交,否則需要定位到二級索引記錄,然后回表對聚簇索引進(jìn)行上述聚簇索引的操作。

一個事務(wù)對新插入的記錄不需要顯示的加鎖,由于事務(wù)id的存在相當(dāng)于加了一個隱式鎖,別的事務(wù)需要加S鎖或者X鎖的時候,先幫之前的事務(wù)生成鎖結(jié)構(gòu),然后為自己生成鎖結(jié)構(gòu),再進(jìn)入阻塞狀態(tài)。隱式鎖起到了延遲加鎖的作用,也許別的事務(wù)不會獲取于隱式鎖沖突的鎖,這時候可以減少內(nèi)存中生成鎖結(jié)構(gòu)。

到此這篇關(guān)于一篇文章帶你了解清楚Mysql 鎖的文章就介紹到這了,更多相關(guān)Mysql 鎖詳解內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • MYSQL 一個巧用字符函數(shù)做數(shù)據(jù)篩選的題

    MYSQL 一個巧用字符函數(shù)做數(shù)據(jù)篩選的題

    這篇文章主要介紹了MYSQL 一個巧用字符函數(shù)做數(shù)據(jù)篩選的題,需要的朋友可以參考下
    2017-05-05
  • MySQL索引優(yōu)化之適合構(gòu)建索引的幾種情況詳解

    MySQL索引優(yōu)化之適合構(gòu)建索引的幾種情況詳解

    我們知道正確的建立索引可以加快數(shù)據(jù)庫的查詢,但是如果索引建立不當(dāng),或者隨意的建立過多索引不僅不會提升數(shù)據(jù)庫的效率,反而在進(jìn)行數(shù)據(jù)更新操作的時候需要耗費系統(tǒng)資源對索引進(jìn)行維護(hù),同時占用大量的存儲空間來對索引進(jìn)行存儲,本文主要講述在哪些情況下適合建立索引
    2022-07-07
  • 詳解MySQL用事件調(diào)度器Event Scheduler創(chuàng)建定時任務(wù)

    詳解MySQL用事件調(diào)度器Event Scheduler創(chuàng)建定時任務(wù)

    事件調(diào)度器(Event Scheduler)是在MySQLv5.1.6中新增的一個功能,它相當(dāng)于一個定時器,可以在指定的時間點執(zhí)行一條SQL語句或一個語句塊,也可以用于在固定間隔重復(fù)執(zhí)行。下面跟著小編一起來學(xué)習(xí)學(xué)習(xí)在MySQL中如何用事件調(diào)度器Event Scheduler創(chuàng)建定時任務(wù)
    2016-08-08
  • Mysql的水平分表與垂直分表的講解

    Mysql的水平分表與垂直分表的講解

    今天小編就為大家分享一篇關(guān)于Mysql的水平分表與垂直分表的講解,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-03-03
  • mysql中Update未加索引導(dǎo)致的微服務(wù)模塊不可用

    mysql中Update未加索引導(dǎo)致的微服務(wù)模塊不可用

    本文主要介紹了mysql中Update未加索引導(dǎo)致的微服務(wù)模塊不可用,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06
  • Mysql存儲過程學(xué)習(xí)筆記--建立簡單的存儲過程

    Mysql存儲過程學(xué)習(xí)筆記--建立簡單的存儲過程

    我們常用的操作數(shù)據(jù)庫語言SQL語句在執(zhí)行的時候需要要先編譯,然后執(zhí)行,而存儲過程(Stored Procedure)是一組為了完成特定功能的SQL語句集,經(jīng)編譯后存儲在數(shù)據(jù)庫中,用戶通過指定存儲過程的名字并給定參數(shù)(如果該存儲過程帶有參數(shù))來調(diào)用執(zhí)行它。
    2014-08-08
  • mysql 8.0.15 安裝配置方法圖文教程(Windows10 X64)

    mysql 8.0.15 安裝配置方法圖文教程(Windows10 X64)

    這篇文章主要為大家詳細(xì)介紹了Windows10 X64 mysql 8.0.15 安裝配置方法圖文教程,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-03-03
  • MySQL left join操作中on和where放置條件的區(qū)別介紹

    MySQL left join操作中on和where放置條件的區(qū)別介紹

    這篇文章主要給大家介紹了關(guān)于MySQL left join操作中on和where放置條件的區(qū)別的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-01-01
  • mysql幻讀詳解實例以及解決辦法

    mysql幻讀詳解實例以及解決辦法

    MySQL中的幻讀只有在讀的時候才會發(fā)生,讀這里特指SELECT操作,下面這篇文章主要給大家介紹了關(guān)于mysql幻讀詳解實例以及解決辦法的相關(guān)資料,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2022-06-06
  • innodb引擎redo文件維護(hù)方法

    innodb引擎redo文件維護(hù)方法

    下面小編就為大家?guī)硪黄猧nnodb引擎redo文件維護(hù)方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-03-03

最新評論