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

MySql,MVCC實(shí)現(xiàn)及其機(jī)制,快照讀在RC,RR下的區(qū)別說明

 更新時(shí)間:2024年04月08日 08:50:35   作者:今吳霜.  
這篇文章主要介紹了MySql,MVCC實(shí)現(xiàn)及其機(jī)制,快照讀在RC,RR下的區(qū)別說明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

一、什么是MVCC

多版本并發(fā)控制

Multiversion Concurrency Control

大部分的MySQL的存儲(chǔ) 引擎,比如InnoDB,F(xiàn)alcon,以及PBXT并不是簡簡單單的使用行鎖機(jī)制。它們都使用了行鎖結(jié)合一種提高并發(fā)的技術(shù),被稱為MVCC(多版本并 發(fā)控制)。MVCC并不單單應(yīng)用在MySQL中,其他的數(shù)據(jù)庫如Oracle,PostgreSQL,以及其他數(shù)據(jù)庫也使用這個(gè)技術(shù)。 

MVCC避免了許多需要加鎖的情形以及降低消耗。這取決于它實(shí)現(xiàn)的方式,它允許非阻塞讀取,在寫的操作的時(shí)候阻塞必要的記錄

MVCC保存了某一時(shí)刻數(shù)據(jù)的一個(gè)快照。意思就是無論事物運(yùn)行了多久,它們都能看到一致的數(shù)據(jù)。也就是說在相同的時(shí)間下,不同的事物看相同表的數(shù)據(jù)是不同的。如果你從來沒有這方面的經(jīng)驗(yàn),可能說這些有點(diǎn)令人困惑。但是在以后這個(gè)會(huì)很容易理解和熟悉的。

每個(gè)存儲(chǔ)引擎實(shí)現(xiàn)MVCC方式都是不同的。有許多種包含了樂觀(optimistic)和悲觀(pessimistic)的并發(fā)控制。我們用簡單的InnoDb的行為來舉例說明MVCC工作方式。

InnoDB實(shí)現(xiàn)MVCC的方法是,它存儲(chǔ)了每一行的兩個(gè)額外的隱藏字段,這兩個(gè)隱藏字段分別記錄了行的創(chuàng)建的時(shí)間和刪除的時(shí)間。在每個(gè)事件發(fā)生的時(shí) 候,每行存儲(chǔ)版本號(hào),而不是存儲(chǔ)事件實(shí)際發(fā)生的時(shí)間。每次事物的開始這個(gè)版本號(hào)都會(huì)增加。自記錄時(shí)間開始,每個(gè)事物都會(huì)保存記錄的系統(tǒng)版本號(hào)。依照事物的 版本來檢查每行的版本號(hào)。在事物隔離級(jí)別為可重復(fù)讀的情況下,來看看怎樣應(yīng)用它。

SELECT

  • InnoDB檢查每行,要確定它符合兩個(gè)標(biāo)準(zhǔn)。
  • InnoDB必須知道行的版本號(hào),這個(gè)行的版本號(hào)至少要和事物版本號(hào)一樣的老。(也就是是說它的版本號(hào)可能少于或者和事物版本號(hào)相同)。這個(gè)既能確定事物開始之前行是存在的,也能確定事物創(chuàng)建或修改了這行。
  • 行的刪除操作的版本一定是未定義的或者大于事物的版本號(hào)。確定了事物開始之前,行沒有被刪除。
  • 符合了以上兩點(diǎn)。會(huì)返回查詢結(jié)果。

INSERT

  • InnoDB記錄了當(dāng)前新增行的系統(tǒng)版本號(hào)。

DELETE

  • InnoDB記錄的刪除行的系統(tǒng)版本號(hào)作為行的刪除ID。

UPDATE

  • InnoDB復(fù)制了一行。這個(gè)新行的版本號(hào)使用了系統(tǒng)版本號(hào)。它也把系統(tǒng)版本號(hào)作為了刪除行的版本。

所有其他記錄的結(jié)果保存是,從未獲得鎖的查詢。這樣它們查詢的數(shù)據(jù)就會(huì)盡可能的快。要確定查詢行要遵循這些標(biāo)準(zhǔn)。缺點(diǎn)是存儲(chǔ)引擎要為每一行存儲(chǔ)更多的數(shù)據(jù),檢查行的時(shí)候要做更多的處理以及其他內(nèi)部的一些操作。

MVCC只能在可重復(fù)讀和可提交讀的隔離級(jí)別下生效。不可提交讀不能使用它的原因是不能讀取符合事物版本的行版本。它們總是讀取最新的行版本??尚蛄谢荒苁褂肕VCC的原因是,它總是要鎖定行。

下面的表說明了在MySQL中不同鎖的模式以及并發(fā)級(jí)別。

在這里插入圖片描述

我們在操作數(shù)據(jù)庫的時(shí)候總是這四大類 讀讀 讀寫 寫讀 寫寫,讀讀肯定是沒有任務(wù)數(shù)據(jù)問題的,但對(duì)事物有了解的同學(xué)就會(huì)知道,讀寫、寫寫操作很容易就會(huì)導(dǎo)致數(shù)據(jù)不一致。

在此之前解決這類問題的常用方式就是 加鎖,聽名字就知道這是個(gè)很復(fù)雜、很耗性能的操作,所以大神們不滿足這個(gè)操作,從而在MySQL里面實(shí)現(xiàn)了MVCC。

MVCC并不是MySQL獨(dú)有的,它是一個(gè)理念,百度百科解釋如下:

Multi-Version Concurrency Control 多版本并發(fā)控制,MVCC 是一種并發(fā)控制的方法,一般在數(shù)據(jù)庫管理系統(tǒng)中,實(shí)現(xiàn)對(duì)數(shù)據(jù)庫的并發(fā)訪問;在編程語言中實(shí)現(xiàn)事務(wù)內(nèi)存。

MVCC里面有一些關(guān)鍵詞,理解這些關(guān)鍵詞,你就明白了什么是MVCC。MVCC是解決讀寫、寫讀導(dǎo)致數(shù)據(jù)不一致的問題,寫寫問題還是需要加鎖來解決。

所以我們可以使用 MVCC + 鎖(樂觀鎖/悲觀鎖)來解決全部的問題。

二、當(dāng)前讀、快照讀

當(dāng)前讀就是讀取最新的數(shù)據(jù),為了保證讀取的是最新且準(zhǔn)確的數(shù)據(jù),所以它在讀取的時(shí)候會(huì)加鎖,防止其它事物操作。

快照讀是不加鎖的方式,當(dāng)一個(gè)事物要操作數(shù)據(jù)庫的時(shí)候,會(huì)在這個(gè)事物的基礎(chǔ)上形成一個(gè)快照,其它的操作就讀取這個(gè)快照。

MVCC就是基于快照讀來實(shí)現(xiàn)的,在MySQL里面的快照讀是基于這樣幾個(gè)關(guān)鍵點(diǎn)來實(shí)現(xiàn)的

  • 三個(gè)隱藏參數(shù) (DB_ROW_ID 隱藏主鍵id、DB_ROLL_PTR 回滾指針、DB_TRX_ID 事物id)
  • undo log 日志
  • read view

三、隱藏字段

假如我們有一張表,里面有兩個(gè)字段,name、age,但實(shí)際上我們表里的數(shù)據(jù)是這樣的

在這里插入圖片描述

3-1、隱藏主鍵

6byte,隱含的自增ID(隱藏主鍵),如果數(shù)據(jù)表沒有主鍵,InnoDB會(huì)自動(dòng)以DB_ROW_ID產(chǎn)生一個(gè)聚簇索引

聚簇索引:數(shù)據(jù)存儲(chǔ)和索引是存在一起的,邏輯上和物理上都是一起的,一個(gè)表只能有一個(gè)聚簇索引。

注:理解聚簇索引可以很好的理解MySQL的索引規(guī)則,感興趣的可以看看這個(gè) MySQL索引詳解

3-2、事物id

記錄這條記錄最后一次操作的事物id

3-3、回滾指針

回滾指針,指向這條記錄的上一個(gè)版本(存儲(chǔ)于rollback segment里),用于配合下面的 undo log。

四、undo log

undo log 日志分為兩種

(1)、 insert undo log 數(shù)據(jù)庫在插入數(shù)據(jù)的時(shí)候產(chǎn)生,只有在當(dāng)前事物回滾的時(shí)候才有用,所以在當(dāng)前事物結(jié)束的時(shí)候它就沒用了,就會(huì)被刪除。

(2)、 update undo log 數(shù)據(jù)庫在更新、刪除的時(shí)候產(chǎn)生,除了當(dāng)前事物會(huì)使用,在快照讀的時(shí)候也會(huì)使用,所以不能隨便刪除,只有在快速讀或事務(wù)回滾不涉及該日志時(shí),對(duì)應(yīng)的日志才會(huì)被purge線程統(tǒng)一清除。

五、Read View

什么是讀視圖呢?數(shù)據(jù)庫的操作都是多個(gè)事物同時(shí)進(jìn)行的,有讀有寫。假如當(dāng)前有兩個(gè)事物,A事物讀取,B事物正在更新數(shù)據(jù)。

在A事物開始的時(shí)候,就形成當(dāng)前數(shù)據(jù)庫的一個(gè)快照,記錄并維護(hù)系統(tǒng)當(dāng)前活躍事務(wù)的ID。read view 主要是用來做可見性判斷的,它會(huì)判斷每條記錄的的數(shù)據(jù),這條數(shù)據(jù)可能是真實(shí)的數(shù)據(jù),也可能是undo log 中的數(shù)據(jù)。

read view 用一個(gè)可見性的算法,來判斷當(dāng)前是讀取真實(shí)的數(shù)據(jù),還是undo log的數(shù)據(jù)。這里可以簡單理解read view 內(nèi)部維護(hù)了一個(gè)事物id列表,里面有最大值和最小值,可以判斷其它事物的id是否在這個(gè)可見范圍內(nèi)。

N、其它

N-1、快照讀在RC和RR下的區(qū)別

  • RC (read-committed)讀已提交, 可能會(huì)導(dǎo)致 不可重復(fù)讀、幻讀
  • RR (repeatable-read)可重復(fù)讀,可能會(huì)導(dǎo)致 不可重復(fù)讀

幻讀 : 事物A查詢數(shù)據(jù)庫查詢出來了20條數(shù)據(jù),然后事物B刪除了2條數(shù)據(jù),這時(shí)候事物A再去查詢發(fā)現(xiàn)只有18條了,從而產(chǎn)生了幻覺。

我們知道在RR級(jí)別下面不會(huì)產(chǎn)生幻讀,之所以不會(huì)產(chǎn)生幻讀,是快照讀在RC和RR下的生成的策略不一樣。

RC隔離級(jí)別下,是每個(gè)快照讀都會(huì)生成并獲取最新的Read View;而在RR隔離級(jí)別下,則是同一個(gè)事務(wù)中的第一個(gè)快照讀才會(huì)創(chuàng)建Read View, 之后的快照讀獲取的都是同一個(gè)Read View。

MySQL/InnoDB定義的4種隔離級(jí)別:

Read Uncommited

  • 可以讀取未提交記錄。

Read Committed (RC)

  • 針對(duì)當(dāng)前讀,RC隔離級(jí)別保證對(duì)讀取到的記錄加鎖 (記錄鎖),存在幻讀現(xiàn)象

Repeatable Read (RR)(默認(rèn))

  • 針對(duì)當(dāng)前讀,RR隔離級(jí)別保證對(duì)讀取到的記錄加鎖 (記錄鎖),同時(shí)保證對(duì)讀取的范圍加鎖,新的滿足查詢條件的記錄不能夠插入 (間隙鎖),不存在幻讀現(xiàn)象。

Serializable

  • 從MVCC并發(fā)控制退化為基于鎖的并發(fā)控制。不區(qū)別快照讀與當(dāng)前讀,所有的讀操作均為當(dāng)前讀,讀加讀鎖 (S鎖),寫加寫鎖 (X鎖)。
  • Serializable隔離級(jí)別下,讀寫沖突,因此并發(fā)度急劇下降,在MySQL/InnoDB下不建議使用。

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • MySQL并發(fā)更新數(shù)據(jù)時(shí)的處理方法

    MySQL并發(fā)更新數(shù)據(jù)時(shí)的處理方法

    在后端開發(fā)中我們不可避免的會(huì)遇見MySQL數(shù)據(jù)并發(fā)更新的情況,作為一名后端研發(fā),如何解決這類問題也是必須要知道的,同時(shí)這也是面試中經(jīng)??疾斓闹R(shí)點(diǎn)。
    2019-05-05
  • linux下mysql亂碼問題的解決方案

    linux下mysql亂碼問題的解決方案

    今天小編就為大家分享一篇關(guān)于linux下mysql亂碼問題的解決方案,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧
    2019-03-03
  • 重裝MySQL最后一步失敗的完美解決方案(經(jīng)驗(yàn)總結(jié))

    重裝MySQL最后一步失敗的完美解決方案(經(jīng)驗(yàn)總結(jié))

    使用MySQL都有過重裝的經(jīng)歷,要是重裝MySQL基本都是在最后一步通不過,究竟是什么原因呢?下面是我總結(jié)的一點(diǎn)經(jīng)驗(yàn),都是血的教訓(xùn)
    2014-06-06
  • mysql視圖之創(chuàng)建可更新視圖的方法詳解

    mysql視圖之創(chuàng)建可更新視圖的方法詳解

    這篇文章主要介紹了mysql視圖之創(chuàng)建可更新視圖的方法,結(jié)合實(shí)例形式分析了mysql可更新視圖的具體創(chuàng)建、使用方法及相關(guān)操作注意事項(xiàng),需要的朋友可以參考下
    2019-12-12
  • mysql多表join時(shí)候update更新數(shù)據(jù)的方法

    mysql多表join時(shí)候update更新數(shù)據(jù)的方法

    如果item表的name字段為''就用resource_library 表的resource_name字段前面加上字符串Review更新它,他們的關(guān)聯(lián)關(guān)系在表resource_review_link中。
    2011-03-03
  • 詳解MySQL?substring()?字符串截取函數(shù)

    詳解MySQL?substring()?字符串截取函數(shù)

    MySQL 查詢數(shù)據(jù)有時(shí)候需要對(duì)數(shù)據(jù)項(xiàng)進(jìn)行日期格式化或截取特定部分的操作,當(dāng)需要對(duì)字符串進(jìn)行截取加工時(shí)用到了 substring() 函數(shù),這篇文章主要介紹了MySQL?substring()?字符串截取函數(shù),需要的朋友可以參考下
    2022-07-07
  • MySQL主從狀態(tài)檢查的實(shí)現(xiàn)

    MySQL主從狀態(tài)檢查的實(shí)現(xiàn)

    這篇文章主要介紹了MySQL主從狀態(tài)檢查的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-02-02
  • 在OneProxy的基礎(chǔ)上實(shí)行MySQL讀寫分離與負(fù)載均衡

    在OneProxy的基礎(chǔ)上實(shí)行MySQL讀寫分離與負(fù)載均衡

    基于Libevent機(jī)制實(shí)現(xiàn),單個(gè)實(shí)例可以實(shí)現(xiàn)25萬的SQL轉(zhuǎn)發(fā)能力,用一個(gè)OneProxy節(jié)點(diǎn)可以帶動(dòng)整個(gè)MySQL集群,為業(yè)務(wù)發(fā)展貢獻(xiàn)一份力量,下面由小編來為大家簡單說說
    2019-05-05
  • mysql5.7 新增的json字段類型用法實(shí)例分析

    mysql5.7 新增的json字段類型用法實(shí)例分析

    這篇文章主要介紹了mysql5.7 新增的json字段類型用法,結(jié)合實(shí)例形式分析了mysql5.7 新增的json字段類型具體功能、使用方法及操作注意事項(xiàng),需要的朋友可以參考下
    2020-02-02
  • Linux下安裝MySQL8.0.11的教程

    Linux下安裝MySQL8.0.11的教程

    這篇文章主要介紹了Linux下安裝MySQL8.0.11的教程,本文圖文并茂給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-12-12

最新評(píng)論