成人午夜视频全免费观看高清-秋霞福利视频一区二区三区-国产精品久久久久电影小说-亚洲不卡区三一区三区一区

二.MySQL鎖機(jī)制詳解-創(chuàng)新互聯(lián)

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

在云夢等地區(qū),都構(gòu)建了全面的區(qū)域性戰(zhàn)略布局,加強(qiáng)發(fā)展的系統(tǒng)性、市場前瞻性、產(chǎn)品創(chuàng)新能力,以專注、極致的服務(wù)理念,為客戶提供成都做網(wǎng)站、網(wǎng)站建設(shè) 網(wǎng)站設(shè)計制作定制網(wǎng)站設(shè)計,公司網(wǎng)站建設(shè),企業(yè)網(wǎng)站建設(shè),成都品牌網(wǎng)站建設(shè),成都全網(wǎng)營銷推廣,成都外貿(mào)網(wǎng)站制作,云夢網(wǎng)站建設(shè)費(fèi)用合理。全局鎖

全局鎖就是對整個數(shù)據(jù)庫實例加鎖。 MySQL提供了一個加全局讀鎖的方法,命令是Flush tables with read lock (FTWRL)。當(dāng)你需要讓整個庫處于只讀狀態(tài)的時候,可以使用這個命令,之后其他線程的以下語句會被阻塞:數(shù)據(jù)更新語句(數(shù)據(jù)的增刪改)、數(shù)據(jù)定義語句(包括建表、修改表結(jié)構(gòu)等)和更新類事務(wù)的提交語句。
全局鎖的典型使用場景是,做全庫邏輯備份。也就是把整庫每個表都select出來存成文本。
然而加全局鎖會有許多問題:

  • 如果你在主庫上備份,那么在備份期間都不能執(zhí)行更新,業(yè)務(wù)基本上就得停擺;
  • 如果你在從庫上備份,那么備份期間從庫不能執(zhí)行主庫同步過來的binlog,會導(dǎo)致主從延遲。

然而為了避免備份數(shù)據(jù)與原數(shù)據(jù)不同,在備份期間加鎖是必要的。在InnoDB引擎中邏輯備份工具是mysqldump。當(dāng)mysqldump使用參數(shù)–single-transaction的時候,導(dǎo)出數(shù)據(jù)之前就會啟動一個事務(wù),來確保拿到一致性視圖。而由于MVCC的支持,這個過程中數(shù)據(jù)是可以正常更新的。

注意:single-transaction方法只適用于所有的表使用事務(wù)引擎的庫。如果有的表使用了不
支持事務(wù)的引擎,那么備份就只能通過FTWRL方法。

表級鎖

MySQL里面表級別的鎖有兩種:一種是表鎖,一種是元數(shù)據(jù)鎖(meta data lock, MDL)。
鎖的語法是locktables…read/write。與FTWRL類似,可以用unlock tables主動釋放鎖,
也可以在客戶端斷開的時候自動釋放。

另一類表級的鎖是MDL(metadata lock)。MDL不需要顯式使用,在訪問一個表的時候會被自動加上。 MDL的作用是,保證讀寫的正確性。你可以想象一下,如果一個查詢正在遍歷一個表中的數(shù)據(jù),而執(zhí)行期間另一個線程對這個表結(jié)構(gòu)做變更,刪了一列,那么查詢線程拿到的結(jié)果跟表結(jié)構(gòu)對不上,肯定是不行的。

當(dāng)對一個表做增刪改查操作的時候,加MDL讀鎖;當(dāng)要對表做結(jié)構(gòu)變更操作的時候,加MDL寫鎖。

表鎖一般是在數(shù)據(jù)庫引擎不支持行鎖的時候才會被用到的。如果你發(fā)現(xiàn)你的應(yīng)用程序里有l(wèi)ock
tables這樣的語句,你需要追查一下,比較可能的情況是:

  • 要么是你的系統(tǒng)現(xiàn)在還在用 MyISAM這類不支持事務(wù)的引擎,那要安排升級換引擎;
  • 要么是你的引擎升級了,但是代碼還沒升級。我見過這樣的情況,最后業(yè)務(wù)開發(fā)就是把lock tables 和 unlock tables 改成 begin 和 commit,問題就解決了。
行鎖

MySQL的行鎖是在引擎層由各個引擎自己實現(xiàn)的。但并不是所有的引擎都支持行鎖,比如
MyISAM引擎就不支持行鎖。不支持行鎖意味著并發(fā)控制只能使用表鎖,對于這種引擎的表,同
一張表上任何時刻只能有一個更新在執(zhí)行,這就會影響到業(yè)務(wù)并發(fā)度。 InnoDB是支持行鎖的,
這也是MyISAM被InnoDB替代的重要原因之一。

兩階段鎖協(xié)議

在InnoDB事務(wù)中,行鎖是在需要的時候才加上的,但并不是不需要了就立刻釋,而是要等到事務(wù)結(jié)束時才釋放。這個就是兩階段鎖協(xié)議。
知道了這個設(shè)定,對我們使用事務(wù)有什么幫助呢?那就是, 如果你的事務(wù)中需要鎖多個行,要把
最可能造成鎖沖突、最可能影響并發(fā)度的鎖盡量往后放。?

行級鎖的使用有什么注意事項?

InnoDB 的?鎖是針對索引字段加的鎖,表級鎖是針對?索引字段加的鎖。當(dāng)我們執(zhí)?UPDATE 、 DELETE 語句時,如果 WHERE 條件中字段沒有命中唯?索引或者索引失效的話,就會導(dǎo)致掃描全表對表中的所有?記錄進(jìn)?加鎖。這個在我們?常?作開發(fā)中經(jīng)常會遇到,?定要多多注意?。?!
不過,很多時候即使?了索引也有可能會?全表掃描,這是因為 MySQL 優(yōu)化器的原因。

意向鎖

如果需要?到表鎖的話,如何判斷表中的記錄沒有?鎖呢?????遍歷肯定是不?,性能太差。我們需要?到?個叫做意向鎖的東東來快速判斷是否可以對某個表使?表鎖。
意向鎖是表級鎖,共有兩種:

  • 意向共享鎖(Intention Shared Lock, IS 鎖) :事務(wù)有意向?qū)Ρ碇械哪承┘庸蚕礞i(S 鎖),加共享鎖前必須先取得該表的 IS 鎖。
  • 意向排他鎖(Intention Exclusive Lock, IX 鎖) :事務(wù)有意向?qū)Ρ碇械哪承┯涗浖优潘i(X鎖),加排他鎖之前必須先取得該表的 IX 鎖。

意向鎖是有數(shù)據(jù)引擎??維護(hù)的,?戶?法?動操作意向鎖,在為數(shù)據(jù)?加共享 / 排他鎖之前,
InnoDB 會先獲取該數(shù)據(jù)?所在在數(shù)據(jù)表的對應(yīng)意向鎖。

意向鎖與S鎖/X鎖的互斥關(guān)系

即對同一對象加S/X鎖時,若該對象上已有意向鎖且與之互斥,那么就會阻塞。

MVCC

全稱Multi-Version Concurrency Control,即多版本并發(fā)控制,主要是為了提高數(shù)據(jù)庫的并發(fā)性能。同一行數(shù)據(jù)平時發(fā)生讀寫請求時,會上鎖阻塞住。但mvcc用更好的方式去處理讀—寫請求,做到在發(fā)生讀—寫請求沖突時不用加鎖。這個讀是指的快照讀,而不是當(dāng)前讀,當(dāng)前讀是一種加鎖操作,是悲觀鎖。MVCC是“維持一個數(shù)據(jù)的多個版本,使讀寫操作沒有沖突”的一個抽象概念

當(dāng)前讀

它讀取的數(shù)據(jù)庫記錄,都是當(dāng)前最新版本,會對當(dāng)前讀取的數(shù)據(jù)進(jìn)行加鎖,防止其他事務(wù)修改數(shù)據(jù)。是悲觀鎖的一種操作。

如下操作都是當(dāng)前讀:(可以發(fā)現(xiàn),增刪改查操作中,只有普通查詢操作不是當(dāng)前讀)

  • select lock in share mode (共享鎖)

  • select for update (排他鎖)

  • update (排他鎖)

  • insert (排他鎖)

  • delete (排他鎖)

  • 串行化事務(wù)隔離級別

快照讀

快照讀的實現(xiàn)是基于多版本并發(fā)控制,即MVCC,既然是多版本,那么快照讀讀到的數(shù)據(jù)不一定是當(dāng)前最新的數(shù)據(jù),有可能是之前歷史版本的數(shù)據(jù)。

如下操作是快照讀:

  • 不加鎖的select操作(注:事務(wù)級別不是串行化)
MVCC解決并發(fā)哪些問題?

mvcc用來解決讀—寫沖突的無鎖并發(fā)控制,就是為事務(wù)分配單向增長時間戳。為每個數(shù)據(jù)修改保存一個版本,版本與事務(wù)時間戳相關(guān)聯(lián)。

讀操作只讀取該事務(wù)開始前數(shù)據(jù)庫快照

解決問題如下:

  • 并發(fā)讀-寫時:可以做到讀操作不阻塞寫操作,同時寫操作也不會阻塞讀操作。

  • 解決臟讀、幻讀、不可重復(fù)讀等事務(wù)隔離問題,但不能解決寫-寫 更新丟失問題。

因此有了下面提高并發(fā)性能的組合拳

  • MVCC + 悲觀鎖:MVCC解決讀寫沖突,悲觀鎖解決寫寫沖突

  • MVCC + 樂觀鎖:MVCC解決讀寫沖突,樂觀鎖解決寫寫沖突

MVCC的實現(xiàn)原理

它的實現(xiàn)原理主要是版本鏈,undo日志Read View來實現(xiàn)的

版本鏈

我們數(shù)據(jù)庫中的每行數(shù)據(jù),除了我們?nèi)庋劭匆姷臄?shù)據(jù),還有幾個隱藏字段,分別是db_trx_id、db_roll_pointer、db_row_id。

  • db_trx_id

    6byte,最近修改(修改/插入)事務(wù)ID:記錄創(chuàng)建這條記錄/最后一次修改該記錄的事務(wù)ID。

  • db_roll_pointer(版本鏈關(guān)鍵)

    7byte,回滾指針,指向這條記錄上一個版本(存儲于rollback segment里)

  • db_row_id

    6byte,隱含的自增ID(隱藏主鍵),如果數(shù)據(jù)表沒有主鍵,InnoDB會自動以db_row_id產(chǎn)生一個聚簇索引。

  • 實際還有一個刪除flag隱藏字段, 記錄被更新刪除并不代表真的刪除,而是刪除flag變了

每次對數(shù)據(jù)庫記錄進(jìn)行改動,都會記錄一條undo日志,每條undo日志也都有一個roll_pointer屬性(INSERT操作對應(yīng)的undo日志沒有該屬性,因為該記錄并沒有更早的版本),可以將這些undo日志都連起來,串成一個鏈表,所以現(xiàn)在的情況就像下圖一樣:

對該記錄每次更新后,都會將舊值放到一條undo日志中,就算是該記錄的一個舊版本,隨著更新次數(shù)的增多,所有的版本都會被roll_pointer屬性連接成一個鏈表,我們把這個鏈表稱之為版本鏈,版本鏈的頭節(jié)點就是當(dāng)前記錄最新的值。另外,每個版本中還包含生成該版本時對應(yīng)的事務(wù)id,這個信息很重要,在根據(jù)ReadView判斷版本可見性的時候會用到。

Read View(讀視圖)

事務(wù)進(jìn)行快照讀操作的時候生產(chǎn)的讀視圖(Read View),在該事務(wù)執(zhí)行的快照讀的那一刻,會生成數(shù)據(jù)庫系統(tǒng)當(dāng)前的一個快照

記錄并維護(hù)系統(tǒng)當(dāng)前活躍事務(wù)的ID(沒有commit,當(dāng)每個事務(wù)開啟時,都會被分配一個ID, 這個ID是遞增的,所以越新的事務(wù),ID值越大),是系統(tǒng)中當(dāng)前不應(yīng)該被本事務(wù)看到的其他事務(wù)id列表。

Read View主要是用來做可見性判斷的, 即當(dāng)我們某個事務(wù)執(zhí)行快照讀的時候,對該記錄創(chuàng)建一個Read View讀視圖,把它比作條件用來判斷當(dāng)前事務(wù)能夠看到哪個版本的數(shù)據(jù),既可能是當(dāng)前最新的數(shù)據(jù),也有可能是該行記錄的undo log里面的某個版本的數(shù)據(jù)。

Read View幾個屬性

  • trx_ids: 當(dāng)前系統(tǒng)活躍(未提交)事務(wù)版本號集合。

  • low_limit_id: 創(chuàng)建當(dāng)前read view 時“當(dāng)前系統(tǒng)大事務(wù)版本號+1”。

  • up_limit_id: 創(chuàng)建當(dāng)前read view 時“系統(tǒng)正處于活躍事務(wù)最小版本號

  • creator_trx_id: 創(chuàng)建當(dāng)前read view的事務(wù)版本號;

在實現(xiàn)上, InnoDB為每個事務(wù)構(gòu)造了一個數(shù)組,用來保存這個事務(wù)啟動瞬間,當(dāng)前正在“活
躍”的所有事務(wù)ID。 “活躍”指的就是,啟動了但還沒提交。
數(shù)組里面事務(wù)ID的最小值記為低水位,當(dāng)前系統(tǒng)里面已經(jīng)創(chuàng)建過的事務(wù)ID的大值加1記為高水
位。
這個視圖數(shù)組和高水位,就組成了當(dāng)前事務(wù)的一致性視圖(read-view)。
而數(shù)據(jù)版本的可見性規(guī)則,就是基于數(shù)據(jù)的row trx_id和這個一致性視圖的對比結(jié)果得到的。
這個視圖數(shù)組把所有的row trx_id 分成了幾種不同的情況。

這樣,對于當(dāng)前事務(wù)的啟動瞬間來說,一個數(shù)據(jù)版本的row trx_id,有以下幾種可能:
1. 如果落在綠色部分,表示這個版本是已提交的事務(wù)或者是當(dāng)前事務(wù)自己生成的,這個數(shù)據(jù)是
可見的;
2. 如果落在紅色部分,表示這個版本是由將來啟動的事務(wù)生成的,是肯定不可見的;
3. 如果落在黃色部分,那就包括兩種情況
a. 若 row trx_id在數(shù)組中,表示這個版本是由還沒提交的事務(wù)生成的,不可見;
b. 若 row trx_id不在數(shù)組中,表示這個版本是已經(jīng)提交了的事務(wù)生成的,可見。

MVCC和事務(wù)隔離級別

上面所講的Read View用于支持RC(Read Committed,讀提交)和RR(Repeatable Read,可重復(fù)讀)隔離級別實現(xiàn)。

  • 在可重復(fù)讀隔離級別(RR)下,只需要在事務(wù)開始的時候創(chuàng)建一致性視圖,之后事務(wù)里的其他查詢都共用這個一致性視圖;
  • 在讀提交隔離級別(RC)下,每一個語句執(zhí)行前都會重新算出一個新的視圖。
  • 在讀提交隔離級別(RC)下的事務(wù)中,每次快照讀都會新生成一個快照和Read View, 這就是我們在RC級別下的事務(wù)中可以看到別的事務(wù)提交的更新的原因

總結(jié):

從以上的描述中我們可以看出來,所謂的MVCC指的就是在使用READ COMMITTD、REPEATABLE READ這兩種隔離級別的事務(wù)在執(zhí)行普通的SEELCT操作時訪問記錄的版本鏈的過程,這樣子可以使不同事務(wù)的讀-寫寫-讀操作并發(fā)執(zhí)行,從而提升系統(tǒng)性能(而不是依靠行鎖)

你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級服務(wù)器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧

網(wǎng)站欄目:二.MySQL鎖機(jī)制詳解-創(chuàng)新互聯(lián)
URL分享:http://jinyejixie.com/article38/dhoppp.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供微信公眾號、網(wǎng)站營銷、靜態(tài)網(wǎng)站、ChatGPT全網(wǎng)營銷推廣、域名注冊

廣告

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

h5響應(yīng)式網(wǎng)站建設(shè)
鹤庆县| 舟曲县| 聂拉木县| 湘潭县| 望江县| 陆川县| 安陆市| 霍林郭勒市| 玉山县| 梓潼县| 宣武区| 南安市| 家居| 德惠市| 渝北区| 宁武县| 光山县| 吉首市| 东莞市| 江陵县| 宾阳县| 湖口县| 海盐县| 望都县| 凤山县| 泰来县| 天峻县| 于都县| 曲沃县| 蒲江县| 奉贤区| 九龙坡区| 珠海市| 女性| 林甸县| 龙门县| 精河县| 嘉定区| 会理县| 班戈县| 甘德县|