傳統(tǒng)mvcc和innodbmvcc的實(shí)現(xiàn)方法

這篇文章主要介紹“傳統(tǒng)mvcc和innodb mvcc的實(shí)現(xiàn)方法”,在日常操作中,相信很多人在傳統(tǒng)mvcc和innodb mvcc的實(shí)現(xiàn)方法問(wèn)題上存在疑惑,小編查閱了各式資料,整理出簡(jiǎn)單好用的操作方法,希望對(duì)大家解答”傳統(tǒng)mvcc和innodb mvcc的實(shí)現(xiàn)方法”的疑惑有所幫助!接下來(lái),請(qǐng)跟著小編一起來(lái)學(xué)習(xí)吧!

10多年的瓊中黎族網(wǎng)站建設(shè)經(jīng)驗(yàn),針對(duì)設(shè)計(jì)、前端、開發(fā)、售后、文案、推廣等六對(duì)一服務(wù),響應(yīng)快,48小時(shí)及時(shí)工作處理。成都全網(wǎng)營(yíng)銷推廣的優(yōu)勢(shì)是能夠根據(jù)用戶設(shè)備顯示端的尺寸不同,自動(dòng)調(diào)整瓊中黎族建站的顯示方式,使網(wǎng)站能夠適用不同顯示終端,在瀏覽器中調(diào)整網(wǎng)站的寬度,無(wú)論在任何一種瀏覽器上瀏覽網(wǎng)站,都能展現(xiàn)優(yōu)雅布局與設(shè)計(jì),從而大程度地提升瀏覽體驗(yàn)。創(chuàng)新互聯(lián)公司從事“瓊中黎族網(wǎng)站設(shè)計(jì)”,“瓊中黎族網(wǎng)站推廣”以來(lái),每個(gè)客戶項(xiàng)目都認(rèn)真落實(shí)執(zhí)行。

        根據(jù)《高性能MySQL》一書的描述,mvcc實(shí)現(xiàn)應(yīng)該大致如下:

        1、每行數(shù)據(jù)后面有兩個(gè)隱藏的字段,一個(gè)字段為更新標(biāo)識(shí),一個(gè)字段為刪除標(biāo)識(shí),記錄內(nèi)容為更新/刪除時(shí)候的系統(tǒng)版本號(hào)。

        2、select過(guò)程中,會(huì)根據(jù)當(dāng)前事務(wù)版本號(hào)去過(guò)濾小于等于的數(shù)據(jù)。

        3、update操作實(shí)際會(huì)新增一行記錄,而并非在原數(shù)據(jù)上修改。

        4、delete也并非物理刪除,而是在刪除標(biāo)識(shí)字段上加上版本號(hào)。

        然而innodb的mvcc并不盡相同??!

        在innodb中,兩個(gè)隱藏字段分別為DATA_TRX_IDDATA_ROLL_PTR(如果沒(méi)有主鍵,則還會(huì)多一個(gè)隱藏的主鍵列,在一些文章中有看到del_flag字段,但是具體它是一個(gè)單獨(dú)字段還是DATA_TRX_ID中的一位,目前還沒(méi)有搞清楚)。

        DATA_TRX_ID

記錄最近更新這條行記錄的事務(wù) ID,大小為 6 個(gè)字節(jié)

        DATA_ROLL_PTR

表示指向該行回滾段(rollback segment)的指針,大小為 7 個(gè)字節(jié),InnoDB 便是通過(guò)這個(gè)指針找到之前版本的數(shù)據(jù)。該行記錄上所有舊版本,在 undo 中都通過(guò)鏈表的形式組織,在網(wǎng)上搜了一下,大概格式如下,它記錄的是每個(gè)版本被修改的數(shù)據(jù),并非是一條操作的反操作。

傳統(tǒng)mvcc和innodb mvcc的實(shí)現(xiàn)方法

所以,實(shí)際上每次進(jìn)行update操作時(shí),并非是會(huì)創(chuàng)建一個(gè)新的副本。而是會(huì)先將就的數(shù)據(jù)行copy進(jìn)undo log中去,隨后修改該數(shù)據(jù)行,并且修改其DATA_TRX_ID 和 DATA_ROLL_ID。

        上面說(shuō)了支撐mvcc功能的列結(jié)構(gòu),那么下來(lái)看一下mysql的四種事務(wù)隔離級(jí)別和mvcc的關(guān)系。

        1.臟讀

        和mvcc沒(méi)有關(guān)系,每次select最新的數(shù)據(jù),別的事務(wù)的數(shù)據(jù)只要已經(jīng)物理寫入或者修改,那么它便會(huì)去讀,直接忽略掉后面的DATA_TRX_ID。

        2.提交讀

        在mvcc的使用上,innodb引入了ReadView 這一方式。在生成一個(gè)ReadView的時(shí)候,會(huì)收集所有目前所有活躍事務(wù)(既還未提交的事務(wù))的版本號(hào)到一個(gè)隊(duì)列中m_ids,并且把當(dāng)前系統(tǒng)版本號(hào)+1,也加入隊(duì)列中。那么就可以找到版本號(hào)的最小值up_limit_id和最大值low_limit_id。在select的過(guò)程中,對(duì)于一條數(shù)據(jù),與m_ids對(duì)比,會(huì)有如下結(jié)果。

        a.小于up_limit_id,說(shuō)明該事務(wù)在ReadView開啟之前已經(jīng)提交,所以為有效數(shù)據(jù)。

        b.大于low_limit_id,說(shuō)明該事物是在ReadView開啟之后才提交的,為無(wú)效數(shù)據(jù),這時(shí)候就要順著undo log鏈表向上查找了,直到找到有效的

        c.如果 up_limit_id<id<=low_limit_id,這個(gè)時(shí)候就要拿到id在m_ids中做比較,如果找到了相同的,則說(shuō)明ReadView建立時(shí),該事務(wù)還未提交,所以為無(wú)效數(shù)據(jù),如果找不到,則為有效數(shù)據(jù)。數(shù)據(jù)無(wú)效處理方法同b。

        ps.在undo log上查找時(shí),并不是只有data_trx_id小于up_limit_id才為有效,滿足條件c也是可以的。

        那么解釋了innodb如何使用mvcc,那么提交讀就好理解了,它在每次select都會(huì)新建一個(gè)ReadView,所以兩次select會(huì)擁有不同的ReadView,那么兩次對(duì)于同一個(gè)數(shù)據(jù)的結(jié)果是可能不同的。

        3.可重復(fù)讀

       同樣用mvcc的可重復(fù)讀就更好解釋了,可重復(fù)讀只在第一次select的時(shí)候建立一次ReadView,在整個(gè)事務(wù)的周期內(nèi)都使用這個(gè)ReadView。所以它就能保證對(duì)于同一數(shù)據(jù)查詢總是相同版本號(hào)的數(shù)據(jù)。

        4.序列化

        實(shí)際上幻讀并非是傳統(tǒng)意義的上的兩次讀取結(jié)果不一致,因?yàn)閺目芍貜?fù)讀的場(chǎng)景上來(lái)看。即使是有新的數(shù)據(jù)插入,因?yàn)閙vcc的原因?qū)嶋H上并不會(huì)對(duì)兩次的結(jié)果產(chǎn)生影響?;米x多發(fā)于 讀-寫 操作,既select * from t1 where id = 1 然后插入id = 1 的數(shù)據(jù),此時(shí)有別的事務(wù)插入了id = 1,結(jié)果報(bào)錯(cuò),這是mvcc無(wú)法解決的問(wèn)題,所以采取的方案便是序列化執(zhí)行。

        最后說(shuō)一下兩種數(shù)據(jù)丟失

第一類丟失更新(回滾丟失,Lostupdate) (通過(guò)設(shè)置隔離級(jí)別可以防止 Repeatable Read)

    這類問(wèn)題產(chǎn)生原因在于由于回滾使得別的事務(wù)提交的數(shù)據(jù)被一并拋棄掉了。

第二類丟失更新(覆蓋丟失/兩次更新問(wèn)題,Second lost update) A事務(wù)覆蓋B事務(wù)已經(jīng)提交的數(shù)據(jù),造成B事務(wù)所做操作丟失:   

    這類問(wèn)題實(shí)際上是由于讀取、更新并非原子操作,在執(zhí)行過(guò)程中,可能已經(jīng)別別的事務(wù)修改掉了,所以這個(gè)時(shí)候你用的是一個(gè)舊的數(shù)據(jù)進(jìn)行更新,最終導(dǎo)致數(shù)據(jù)出現(xiàn)錯(cuò)亂。比如說(shuō)另外一個(gè)已經(jīng)修改為1100,你再來(lái)進(jìn)行修改為1000的基礎(chǔ)上加100,那么這樣就丟失了部分?jǐn)?shù)據(jù)。

    第一類問(wèn)題可以通過(guò)數(shù)據(jù)庫(kù)的隔離級(jí)別來(lái)解決掉,對(duì)于第二類就需要在業(yè)務(wù)代碼中進(jìn)行了,比如采用select for update這樣的操作,或者加上時(shí)間版本號(hào)來(lái)防止問(wèn)題的發(fā)生。

到此,關(guān)于“傳統(tǒng)mvcc和innodb mvcc的實(shí)現(xiàn)方法”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)?lái)更多實(shí)用的文章!

當(dāng)前題目:傳統(tǒng)mvcc和innodbmvcc的實(shí)現(xiàn)方法
網(wǎng)站鏈接:http://muchs.cn/article42/jophhc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供小程序開發(fā)企業(yè)建站、網(wǎng)站導(dǎo)航、微信小程序、網(wǎng)站收錄、網(wǎng)站改版

廣告

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

成都定制網(wǎng)站建設(shè)