溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

MySQL中MVCC與BufferPool緩存機(jī)制是什么

發(fā)布時(shí)間:2022-05-25 13:51:49 來源:億速云 閱讀:158 作者:iii 欄目:開發(fā)技術(shù)

本篇內(nèi)容主要講解“MySQL中MVCC與BufferPool緩存機(jī)制是什么”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實(shí)用性強(qiáng)。下面就讓小編來帶大家學(xué)習(xí)“MySQL中MVCC與BufferPool緩存機(jī)制是什么”吧!

    一、MVCC機(jī)制

    • MVCC(Multi Version Concurrency Control),MySQL(默認(rèn))RR隔離級(jí)別就是通過該機(jī)制來保證的,對(duì)一行數(shù)據(jù)的讀與寫兩個(gè)操作默認(rèn)是不會(huì)通過加鎖互斥來保證隔離性的

    • 串行化隔離級(jí)別是為了保證較高的隔離性,是通過將所有操作加鎖互斥來實(shí)現(xiàn)的

    • MySQL在RC隔離級(jí)別和RR隔離級(jí)別下都實(shí)現(xiàn)了MVCC機(jī)制

    • RC每次查詢都會(huì)創(chuàng)建一個(gè)reade-view,而RR在創(chuàng)建完read-view之后,在不提交事務(wù)之前,每次查詢還是第一次創(chuàng)建的read-view

    undo日志版本鏈與read-view機(jī)制

    • undo日志版本鏈?zhǔn)侵敢恍袛?shù)據(jù)被多個(gè)事務(wù)一次修改后,當(dāng)每個(gè)事務(wù)修改完之后,MySQL會(huì)保留修改前的數(shù)據(jù)undo回滾日志,并且用兩個(gè)隱藏字段trx_id和roll_pointer把只寫undo日志串聯(lián)起來形成一個(gè)歷史記錄版本鏈.

    • RR隔離級(jí)別,當(dāng)事務(wù)開啟,執(zhí)行任何SQL時(shí)會(huì)生成當(dāng)前事務(wù)的read-view一致性視圖,該視圖在事務(wù)結(jié)束之前都不會(huì)變化(如果是RC隔離界別在每次執(zhí)行查詢SQL時(shí)都會(huì)重新生成最新的read-view),這個(gè)視圖由執(zhí)行查詢時(shí)所有未提交的事務(wù)id數(shù)組(數(shù)組里最小的id為min_id)和已創(chuàng)建的最大事務(wù)id(max_id)組成,事務(wù)里任何SQL查詢結(jié)果需要從對(duì)應(yīng)版本鏈里的最新數(shù)據(jù)開始逐條跟read-view作比對(duì),從而得到最終的結(jié)果

    版本鏈比對(duì)規(guī)則

    • 如果row的trx_id落在綠色部分(trx < min_id),表示這個(gè)版本是已提交的事務(wù)生成的,這個(gè)數(shù)據(jù)是可見的

    • 如果row的trx_id落在紅色部分(trx > max_id),表示這個(gè)版本是由將來啟動(dòng)的(未開始)事務(wù)生成的,是不可見的(若row的trx_id就是當(dāng)前自己的事務(wù)是可見的)

    • 如果 row 的 trx_id 落在黃色部分(min_id <= trx_id <= max_id),那就包括兩種情況

      • 若 row 的 trx_id 在視圖數(shù)組中,表示這個(gè)版本是由還沒提交的事務(wù)生成的不可見(若 row 的 trx_id 就是當(dāng)前自己的事務(wù)是可見的)

      • 若 row 的 trx_id 不在視圖數(shù)組中,表示這個(gè)版本是已經(jīng)提交了的事務(wù)生成的可見

    MySQL中MVCC與BufferPool緩存機(jī)制是什么

    二、BufferPool機(jī)制

    InnoDB執(zhí)行的BufferPool緩存機(jī)制:

    MySQL中MVCC與BufferPool緩存機(jī)制是什么

    InnoDB的SQL執(zhí)行流程:

    • 當(dāng)客戶端執(zhí)行一條修改的SQL,需要經(jīng)過Server層,再調(diào)用具體的執(zhí)行引擎

    • 加載數(shù)據(jù)頁,把需要修改數(shù)據(jù)所在的數(shù)據(jù)頁,緩存到BufferPool

    • 修改前寫undo日志,記錄更改前數(shù)據(jù),如果事務(wù)執(zhí)行失敗,使用undo日志進(jìn)行數(shù)據(jù)回滾

    • 更新BufferPool中的數(shù)據(jù)

    • 準(zhǔn)備提交事務(wù)寫redo日志,保存操作記錄。redo日志用來恢復(fù)已提交事務(wù)的BufferPool

    • 準(zhǔn)備提交事務(wù)寫binlog日志,保存操作記錄。binlog日志用來恢復(fù)磁盤數(shù)據(jù)

    • 事務(wù)提交完成,此時(shí)binlog日志寫入成功,并且在redo日志中記錄了commit標(biāo)記。事務(wù)提交完成后binlog日志和redo日志數(shù)據(jù)保持一致

    • 數(shù)據(jù)持久化,IO線程不定期把BufferPool中的數(shù)據(jù)隨機(jī)寫入到磁盤,完成持久化

    三、總結(jié)

    MVCC實(shí)現(xiàn)機(jī)制(為什么同一個(gè)事務(wù)第一次查詢出來之后,就算其它事務(wù)把新數(shù)據(jù)修改了,當(dāng)前事務(wù)還是看到之前的數(shù)據(jù))

    • 它內(nèi)部實(shí)際有個(gè)undo日志版本鏈,然后在事務(wù)第一次查詢的時(shí)候,它會(huì)生成一個(gè)read-view一致性視圖,然后我們后面所有查詢的數(shù)據(jù)都會(huì)根據(jù)我們的那個(gè)undo日志版本鏈去跟我們當(dāng)前的read-view里面按照一定的規(guī)則逐行去比對(duì)查找對(duì)應(yīng)的數(shù)據(jù)

    BufferPool機(jī)制

    • 數(shù)據(jù)庫的增刪改查都是直接操作BufferPool的,當(dāng)我們執(zhí)行一條修改的SQL經(jīng)歷過Server層之后會(huì)調(diào)用具體的執(zhí)行引擎,然后將相關(guān)的數(shù)據(jù)頁加載到BufferPool中,修改前寫undo日志,記錄修改前的數(shù)據(jù)為了方便事務(wù)失敗之后的回滾,然后更新BufferPool,準(zhǔn)備提交事務(wù)寫redo日志保存操作記錄,因?yàn)槿绻鸐ySQL宕機(jī)了會(huì)從redo日志中將數(shù)據(jù)恢復(fù)到BufferPool中,然后會(huì)寫binlog日志,保存操作記錄,因?yàn)楫?dāng)我們刪除數(shù)據(jù)庫跑路時(shí),binlog是用來恢復(fù)磁盤數(shù)據(jù)的,事務(wù)提交完成后,binlog日志寫入成功,并且在redo日志記錄提交標(biāo)記,此時(shí)redo日志和binlog日志數(shù)據(jù)一致,而redo日志采用順序IO寫入,這樣效率堪比內(nèi)存操作。對(duì)于數(shù)據(jù)持久化,InnoDB會(huì)有個(gè)后臺(tái)線程定時(shí)去將緩存刷到磁盤里

    為什么MySQL不能直接更新磁盤上的數(shù)據(jù)而是設(shè)置了這么一套復(fù)雜的機(jī)制來執(zhí)行SQL

    • 因?yàn)閬硪粋€(gè)請(qǐng)求直接對(duì)磁盤文件進(jìn)行隨機(jī)讀寫,然后更新磁盤文件里的數(shù)據(jù)性能可能相當(dāng)差.

    • 因?yàn)?strong>磁盤隨機(jī)讀寫的性能是非常差的,所以直接更新磁盤文件時(shí)不能讓數(shù)據(jù)庫抗住高并發(fā)的

    • MySQL這套機(jī)制看起來很復(fù)雜,但它可以保證每個(gè)更新請(qǐng)求都是更新內(nèi)存BufferPool,然后順序?qū)懭罩疚募?,同時(shí)還能保證各種異常情況下的數(shù)據(jù)一致性

    • 更新內(nèi)存的性能是極高的,然后順序?qū)懘疟P上的日志文件的性能也是非常高的,要遠(yuǎn)高于隨機(jī)讀寫磁盤文件,正是通過這套機(jī)制,才能讓我們的MySQL數(shù)據(jù)庫在較高配置的機(jī)器上每秒可以抗下幾千甚至上完的讀寫請(qǐng)求

    到此,相信大家對(duì)“MySQL中MVCC與BufferPool緩存機(jī)制是什么”有了更深的了解,不妨來實(shí)際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!

    向AI問一下細(xì)節(jié)

    免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

    AI