av激情亚洲男人的天堂国语,日韩欧美精品一中文字幕,无码av一区二区三区无码,国产又色又爽又刺激的a片,国产又色又爽又刺激的a片

細(xì)說InnoDB底層原理

InnoDB,是MySQL的數(shù)據(jù)庫(kù)引擎之一,現(xiàn)為MySQL的默認(rèn)存儲(chǔ)引擎,為MySQL AB發(fā)布binary的標(biāo)準(zhǔn)之一。InnoDB由Innobase Oy公司所開發(fā),2006年五月時(shí)由甲骨文公司并購(gòu)。與傳統(tǒng)的ISAM與MyISAM相比,InnoDB的最大特色就是支持了ACID兼容的事務(wù)(Transaction)功能,類似于PostgreSQL,下面詳細(xì)講解一下InnoDB底層原理。

成都創(chuàng)新互聯(lián)秉承實(shí)現(xiàn)全網(wǎng)價(jià)值營(yíng)銷的理念,以專業(yè)定制企業(yè)官網(wǎng),成都網(wǎng)站制作、網(wǎng)站設(shè)計(jì)、外貿(mào)網(wǎng)站建設(shè),重慶小程序開發(fā),網(wǎng)頁(yè)設(shè)計(jì)制作,手機(jī)網(wǎng)站開發(fā),全網(wǎng)營(yíng)銷推廣幫助傳統(tǒng)企業(yè)實(shí)現(xiàn)“互聯(lián)網(wǎng)+”轉(zhuǎn)型升級(jí)專業(yè)定制企業(yè)官網(wǎng),公司注重人才、技術(shù)和管理,匯聚了一批優(yōu)秀的互聯(lián)網(wǎng)技術(shù)人才,對(duì)客戶都以感恩的心態(tài)奉獻(xiàn)自己的專業(yè)和所長(zhǎng)。

存儲(chǔ)引擎

很多文章都是直接開始介紹有哪些存儲(chǔ)引擎,并沒有去介紹存儲(chǔ)引擎本身。那么究竟什么是存儲(chǔ)引擎?不知道大家有沒有想過,MySQL是如何存儲(chǔ)我們丟進(jìn)去的數(shù)據(jù)的?

其實(shí)存儲(chǔ)引擎也很簡(jiǎn)單,我認(rèn)為就是一種存儲(chǔ)解決方案,實(shí)現(xiàn)了新增數(shù)據(jù)、更新數(shù)據(jù)和建立索引等等功能。

有哪些已有的存儲(chǔ)引擎可以讓我們選擇呢?

InnoDB、MyISAM、Memory、CSV、Archive、Blackhole、Merge、Federated、Example

種類很多,但是常用的存儲(chǔ)引擎目前就只有InnoDB和MyISAM,我也會(huì)著重來介紹這兩種存儲(chǔ)引擎。

InnoDB是目前使用最廣的MySQL存儲(chǔ)引擎,MySQL從5.5版本開始InnoDB就已經(jīng)是默認(rèn)的存儲(chǔ)引擎了。那你知道為什么InnoDB被廣泛的使用呢?先把這個(gè)問題放一放,我們先來了解一下InnoDB存儲(chǔ)引擎的底層原理。

InnoDB的內(nèi)存架構(gòu)主要分為三大塊,緩沖池(Buffer Pool)、重做緩沖池(Redo Log Buffer)和額外內(nèi)存池

緩沖池

InnoDB為了做數(shù)據(jù)的持久化,會(huì)將數(shù)據(jù)存儲(chǔ)到磁盤上。但是面對(duì)大量的請(qǐng)求時(shí),CPU的處理速度和磁盤的IO速度之間差距太大,為了提高整體的效率, InnoDB引入了緩沖池。

當(dāng)有請(qǐng)求來查詢數(shù)據(jù)時(shí),如果緩存池中沒有,就會(huì)去磁盤中查找,將匹配到的數(shù)據(jù)放入緩存池中。同樣的,如果有請(qǐng)求來修改數(shù)據(jù),MySQL并不會(huì)直接去修改磁盤,而是會(huì)修改已經(jīng)在緩沖池的頁(yè)中的數(shù)據(jù),然后再將數(shù)據(jù)刷回磁盤,這就是緩沖池的作用,加速讀,加速寫,減少與磁盤的IO交互。

緩沖池說白了就是把磁盤中的數(shù)據(jù)丟到內(nèi)存,那既然是內(nèi)存就會(huì)存在沒有內(nèi)存空間可以分配的情況。所以緩沖池采用了LRU算法,在緩沖池中沒有空閑的頁(yè)時(shí),來進(jìn)行頁(yè)的淘汰。但是采用這種算法會(huì)帶來一個(gè)問題叫做緩沖池污染。

當(dāng)你在進(jìn)行批量掃描甚至全表掃描時(shí),可能會(huì)將緩沖池中的熱點(diǎn)頁(yè)全部替換出去。這樣以來可能會(huì)導(dǎo)致MySQL的性能斷崖式下降。所以InnoDB對(duì)LRU做了一些優(yōu)化,規(guī)避了這個(gè)問題。

MySQL采用日志先行,在真正寫數(shù)據(jù)之前,會(huì)首先記錄一個(gè)日志,叫Redo Log,會(huì)定期的使用CheckPoint技術(shù)將新的Redo Log刷入磁盤,這個(gè)后面會(huì)講。

除了數(shù)據(jù)之外,里面還存儲(chǔ)了索引頁(yè)、Undo頁(yè)、插入緩沖、自適應(yīng)哈希索引、InnoDB鎖信息和數(shù)據(jù)字典。下面選幾個(gè)比較重要的來簡(jiǎn)單聊一聊。

插入緩沖

插入緩沖針對(duì)的操作是更新或者插入,我們考慮最壞的情況,那就是需要更新的數(shù)據(jù)都不在緩沖池中。那么此時(shí)會(huì)有下面兩種方案。

來一條數(shù)據(jù)就直接寫入磁盤等數(shù)據(jù)達(dá)到某個(gè)閾值(例如50條)才批量的寫入磁盤很明顯,第二種方案要好一點(diǎn),減少了與磁盤IO的交互。

兩次寫

鑒于都聊到了插入緩沖,我就不得不需要提一嘴兩次寫,因?yàn)槲艺J(rèn)為這兩個(gè)InnoDB的特性是相輔相成的。

插入緩沖提高了MySQL的性能,而兩次寫則在此基礎(chǔ)上提高了數(shù)據(jù)的可靠性。我們知道,當(dāng)數(shù)據(jù)還在緩沖池中的時(shí)候,當(dāng)機(jī)器宕機(jī)了,發(fā)生了寫失效,有Redo Log來進(jìn)行恢復(fù)。但是如果是在從緩沖池中將數(shù)據(jù)刷回磁盤的時(shí)候宕機(jī)了呢?

這種情況叫做部分寫失效,此時(shí)重做日志就無法解決問題。

無水干貨:InnoDB底層原理無水干貨:InnoDB底層原理

在刷臟頁(yè)時(shí),并不是直接刷入磁盤,而是copy到內(nèi)存中的Doublewrite Buffer中,然后再拷貝至磁盤共享表空間(你可以就理解為磁盤)中,每次寫入1M,等copy完成后,再將Doublewrite Buffer中的頁(yè)寫入磁盤文件。

有了兩次寫機(jī)制,即使在刷臟頁(yè)時(shí)宕機(jī)了,在實(shí)例恢復(fù)的時(shí)候也可以從共享表空間中找到Doublewrite Buffer的頁(yè)副本,直接將其覆蓋原來的數(shù)據(jù)頁(yè)即可。

自適應(yīng)哈希索引

自適應(yīng)索引就跟JVM在運(yùn)行過程中,會(huì)動(dòng)態(tài)的把某些熱點(diǎn)代碼編譯成Machine Code一樣,InnoDB會(huì)監(jiān)控對(duì)所有索引的查詢,對(duì)熱點(diǎn)訪問的頁(yè)建立哈希索引,以此來提升訪問速度。

你可能多次看到了一個(gè)關(guān)鍵字頁(yè),接下來那我們就來聊一下頁(yè)是什么?

頁(yè)

頁(yè),是InnoDB中數(shù)據(jù)管理的最小單位。當(dāng)我們查詢數(shù)據(jù)時(shí),其是以頁(yè)為單位,將磁盤中的數(shù)據(jù)加載到緩沖池中的。同理,更新數(shù)據(jù)也是以頁(yè)為單位,將我們對(duì)數(shù)據(jù)的修改刷回磁盤。每頁(yè)的默認(rèn)大小為16k,每頁(yè)中包含了若干行的數(shù)據(jù),頁(yè)的結(jié)構(gòu)如下圖所示。

無水干貨:InnoDB底層原理無水干貨:InnoDB底層原理

不用太糾結(jié)每個(gè)區(qū)是干嘛的,我們只需要知道這樣設(shè)計(jì)的好處在哪兒。每一頁(yè)的數(shù)據(jù),可以通過FileHeader中的上一下和下一頁(yè)的數(shù)據(jù),頁(yè)與頁(yè)之間可以形成雙向鏈表。因?yàn)樵趯?shí)際的物理存儲(chǔ)上,數(shù)據(jù)并不是連續(xù)存儲(chǔ)的。你可以把他理解成G1的Region在內(nèi)存中的分布。

而一頁(yè)中所包含的行數(shù)據(jù),行與行之間則形成了單向鏈表。我們存入的行數(shù)據(jù)最終會(huì)到User Records中,當(dāng)然最初User Records并不占據(jù)任何存儲(chǔ)空間。隨著我們存入的數(shù)據(jù)越來越多,User Records會(huì)越來越大,F(xiàn)ree Space的空間會(huì)越來越小,直到被占用完,就會(huì)申請(qǐng)新的數(shù)據(jù)頁(yè)。

User Records中的數(shù)據(jù),是按照主鍵id來進(jìn)行排序的,當(dāng)我們按照主鍵來進(jìn)行查找時(shí),會(huì)沿著這個(gè)單向鏈表一直往后找,

重做日志緩沖

上面聊過,InnoDB中緩沖池中的頁(yè)數(shù)據(jù)更新會(huì)先于磁盤數(shù)據(jù)更新的,InnoDB也會(huì)采用日志先行(Write Ahead Log)策略來刷新數(shù)據(jù),什么意思呢?當(dāng)事務(wù)開始時(shí),會(huì)先記錄Redo Log到Redo Log Buffer中,然后再更新緩沖池頁(yè)數(shù)據(jù)。

Redo Log Buffer中的數(shù)據(jù)會(huì)按照一定的頻率寫到重做日志中去。被更改過的頁(yè)就會(huì)被標(biāo)記成臟頁(yè),InnoDB會(huì)根據(jù)CheckPoint機(jī)制來將臟頁(yè)刷到磁盤。

日志

上面提到了Redo log,這一小節(jié)就專門來講一講日志,日志分為如下兩個(gè)維度。

MySQL層面

InnoDB層面

MySQL日志

MySQL的日志可以分為錯(cuò)誤日志、二進(jìn)制文件、查詢?nèi)罩竞蜐M查詢?nèi)罩尽?/p>

錯(cuò)誤日志 很好理解,就是服務(wù)運(yùn)行過程中發(fā)生的嚴(yán)重錯(cuò)誤日志。當(dāng)我們的數(shù)據(jù)庫(kù)無法啟動(dòng)時(shí),就可以來這里看看具體不能啟動(dòng)的原因是什么二進(jìn)制文件 它有另外一個(gè)名字你應(yīng)該熟悉,叫Binlog,其記錄了對(duì)數(shù)據(jù)庫(kù)所有的更改。查詢?nèi)罩?記錄了來自客戶端的所有語(yǔ)句慢查詢?nèi)罩?這里記錄了所有響應(yīng)時(shí)間超過閾值的SQL語(yǔ)句,這個(gè)閾值我們可以自己設(shè)置,參數(shù)為long_query_time,其默認(rèn)值為10s,且默認(rèn)是關(guān)閉的狀態(tài),需要手動(dòng)的打開。

InnoDB日志

InnoDB日志就只有兩種,Redo Log和Undo Log,

Redo Log 重做日志,用于記錄事務(wù)操作的變化,且記錄的是修改之后的值。不管事務(wù)是否提交都會(huì)記錄下來。例如在更新數(shù)據(jù)時(shí),會(huì)先將更新的記錄寫到Redo Log中,再更新緩存中頁(yè)中的數(shù)據(jù)。然后按照設(shè)置的更新策略,將內(nèi)存中的數(shù)據(jù)刷回磁盤。Undo Log 記錄的是記錄的事務(wù)開始之前的一個(gè)版本,可用于事務(wù)失敗之后發(fā)生的回滾。Redo Log記錄的是具體某個(gè)數(shù)據(jù)頁(yè)上的修改,只能在當(dāng)前Server使用,而Binlog可以理解為可以給其他類型的存儲(chǔ)引擎使用。這也是Binlog的一個(gè)重要作用,那就是主從復(fù)制,另外一個(gè)作用是數(shù)據(jù)恢復(fù)。

上面提到過,Binlog中記錄了所有對(duì)數(shù)據(jù)庫(kù)的修改,其記錄日志有三種格式。分別是Statement、Row和MixedLevel。

Statement 記錄所有會(huì)修改數(shù)據(jù)的SQL,其只會(huì)記錄SQL,并不需要記錄下這個(gè)SQL影響的所有行,減少了日志量,提高了性能。但是由于只是記錄執(zhí)行語(yǔ)句,不能保證在Slave節(jié)點(diǎn)上能夠正確執(zhí)行,所以還需要額外的記錄一些上下文信息Row 只保存被修改的記錄,與Statement只記錄執(zhí)行SQL來比較,Row會(huì)產(chǎn)生大量的日志。但是Row不用記錄上下文信息了,只需要關(guān)注被改成啥樣就行。MixedLevel 就是Statement和Row混合使用。具體使用哪種日志,需要根據(jù)實(shí)際情況來決定。例如一條UPDATE語(yǔ)句更新了很多的數(shù)據(jù),采用Statement會(huì)更加節(jié)省空間,但是相對(duì)的,Row會(huì)更加的可靠。

InnoDB和MyISAM的區(qū)別

由于MyISAM并不常用,我也不打算去深究其底層的一些原理和實(shí)現(xiàn)。我們?cè)谶@里簡(jiǎn)單的對(duì)比一下這兩個(gè)存儲(chǔ)引擎的區(qū)別就好。我們分點(diǎn)來一點(diǎn)點(diǎn)描述。

事務(wù) InnoDB支持事務(wù)、回滾、事務(wù)安全和奔潰恢復(fù)。而MyISAM不支持,但查詢的速度要比InnoDB更快主鍵 InnoDB規(guī)定,如果沒有設(shè)置主鍵,就自動(dòng)的生成一個(gè)6字節(jié)的主鍵,而MyISAM允許沒有任何索引和主鍵的存在,索引就是行的地址外鍵 InnoDB支持外鍵,而MyISAM不支持表鎖 InnoDB支持行鎖和表鎖,而MyISAM只支持表鎖全文索引 InnoDB不支持全文索引,但是可以用插件來實(shí)現(xiàn)相應(yīng)的功能,而MyISAM是本身就支持全本索引行數(shù) InnoDB獲取行數(shù)時(shí),需要掃全表。而MyISAM保存了當(dāng)前表的總行數(shù),直接讀取即可。所以,簡(jiǎn)單總結(jié)一下,MyISAM只適用于查詢大于更新的場(chǎng)景,如果你的系統(tǒng)查詢的情況占絕大多數(shù)(例如報(bào)表系統(tǒng))就可以使用MyISAM來存儲(chǔ),除此之外,都建議使用InnoDB。

End

由于時(shí)間的原因,本文只是簡(jiǎn)單的聊了聊InnoDB的整體架構(gòu),并沒有很深入的去聊某些點(diǎn)。例如InnoDB是如何改進(jìn)來解決緩沖池污染的,其算法具體是什么,checkpoint是如何工作的等等,只是做一個(gè)簡(jiǎn)單的了解,之后如果有時(shí)間的話再細(xì)聊。


文章題目:細(xì)說InnoDB底層原理
網(wǎng)頁(yè)地址:http://uogjgqi.cn/article/dhjcgos.html
掃二維碼與項(xiàng)目經(jīng)理溝通

我們?cè)谖⑿派?4小時(shí)期待你的聲音

解答本文疑問/技術(shù)咨詢/運(yùn)營(yíng)咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流