溫馨提示×

溫馨提示×

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

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

InnoDB的內(nèi)存結(jié)構(gòu)及特性

發(fā)布時間:2021-09-03 14:15:08 來源:億速云 閱讀:130 作者:chen 欄目:大數(shù)據(jù)

本篇內(nèi)容介紹了“InnoDB的內(nèi)存結(jié)構(gòu)及特性”的有關(guān)知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

    常言說得好,每個成功男人背后都有一個為他默默付出的女人,而對于MySQL來說,這個“人”就是InnoDB存儲引擎。  
    
?MySQL區(qū)別于其他數(shù)據(jù)庫的最為重要的特點就是其插件式的表存儲引擎。   而在眾多存儲引擎中,InnoDB是最為常用的存儲引擎。   從MySQL5.5.8版本開始,InnoDB存儲引擎是默認(rèn)的存儲引擎。  
    

?InnoDB存儲引擎支持事務(wù),其設(shè)計目標(biāo)主要面向在線事務(wù)處理(OLTP)的應(yīng)用。其特點是行鎖設(shè)計、支持外鍵,并支持非鎖定讀,即默認(rèn)讀操作不會產(chǎn)生鎖。


?InnoDB通過使用多版本并發(fā)控制(MVCC)來獲取高并發(fā)性,并且實現(xiàn)了SQL標(biāo)準(zhǔn)的4中隔離級別,默認(rèn)為REPEATABLE級別。同時,使用一種被稱為next-key-locking的策略來避免幻讀現(xiàn)象的產(chǎn)生。除此之外,InnoDB存儲引擎還提供了插入緩沖(insert buffer)、二次寫(double write)、自適應(yīng)哈希索引(adaptive hash index)、預(yù)讀(read ahead)等高性能和高可用的功能。

InnoDB的內(nèi)存結(jié)構(gòu)及特性

?上圖詳細(xì)顯示了InnoDB存儲引擎的體系架構(gòu),從圖中可見,InnoDB存儲引擎由內(nèi)存池,后臺線程和磁盤文件三大部分組成。接下來我們就來簡單了解一下內(nèi)存相關(guān)的概念和原理。    
緩沖池

?InnoDB存儲引擎是基于磁盤存儲的,并將其中的記錄按照頁的方式進行管理。但是由于CPU速度和磁盤速度之間的鴻溝,基于磁盤的數(shù)據(jù)庫系統(tǒng)通常使用緩沖池記錄來提高數(shù)據(jù)庫的的整體性能。

?在數(shù)據(jù)庫中進行讀取操作,首先將從磁盤中讀到的頁放在緩沖池中,下次再讀相同的頁中時,首先判斷該頁是否在緩沖池中。若在緩沖池中,稱該頁在緩沖池中被命中,直接讀取該頁。否則,讀取磁盤上的頁。

?對于數(shù)據(jù)庫中頁的修改操作,則首先修改在緩沖池中的頁,然后再以一定的頻率刷新到磁盤上。頁從緩沖池刷新回磁盤的操作并不是在每次頁發(fā)生更新時觸發(fā),而是通過一種稱為CheckPoint的機制刷新回磁盤。

?所以,緩沖池的大小直接影響著數(shù)據(jù)庫的整體性能,可以通過配置參數(shù)innodb_buffer_pool_size來設(shè)置。

?具體來看,緩沖池中緩存的數(shù)據(jù)頁類型有:索引頁、數(shù)據(jù)頁、undo頁、插入緩沖(insert buffer)、自適應(yīng)哈希索引(adaptive hash index)、InnoDB存儲的鎖信息(lock info)和數(shù)據(jù)字典信息(data dictionary)。

?在架構(gòu)圖上可以看到,InnoDB存儲引擎的內(nèi)存區(qū)域除了有緩沖池之外,還有重做日志緩沖和額外內(nèi)存池。InnoDB存儲引擎首先將重做日志信息先放到這個緩沖區(qū)中,然后按照一定頻率將其刷新到重做日志文件中。重做日志緩沖一般不需要設(shè)置的很大,該值可由配置參數(shù)innodb_log_buffer_size控制。

 
數(shù)據(jù)頁和索引頁

?Page是Innodb存儲的最基本結(jié)構(gòu),也是Innodb磁盤管理的最小單位,與數(shù)據(jù)庫相關(guān)的所有內(nèi)容都存儲在Page結(jié)構(gòu)里。Page分為幾種類型,數(shù)據(jù)頁和索引頁就是其中最為重要的兩種類型。

 
插入緩沖(Insert Buffer)

?我們都知道,在InnoDB引擎上進行插入操作時,一般需要按照主鍵順序進行插入,這樣才能獲得較高的插入性能。當(dāng)一張表中存在非聚簇的且不唯一的索引時,在插入時,數(shù)據(jù)頁的存放還是按照主鍵進行順序存放,但是對于非聚簇索引葉節(jié)點的插入不再是順序的了,這時就需要離散的訪問非聚簇索引頁,由于隨機讀取的存在導(dǎo)致插入操作性能下降。

?InnoDB為此設(shè)計了Insert Buffer來進行插入優(yōu)化。對于非聚簇索引的插入或者更新操作,不是每一次都直接插入到索引頁中,而是先判斷插入的非聚集索引是否在緩沖池中,若在,則直接插入;若不在,則先放入到一個Insert Buffer中??此茢?shù)據(jù)庫這個非聚集的索引已經(jīng)查到葉節(jié)點,而實際沒有,這時存放在另外一個位置。然后再以一定的頻率和情況進行Insert Buffer和非聚簇索引頁子節(jié)點的合并操作。這時通常能夠?qū)⒍鄠€插入合并到一個操作中,這樣就大大提高了對于非聚簇索引的插入性能。

 
兩次寫(Double Write)

?如果說Insert Buffer給InnoDB存儲引擎帶來了性能上的提升,那么Double Write帶給InnoDB存儲引擎的是數(shù)據(jù)頁的可靠性。

InnoDB的內(nèi)存結(jié)構(gòu)及特性  
doublewrite示意圖

?如上圖所示,Double Write由兩部分組成,一部分是內(nèi)存中的double write buffer,大小為2MB,另一部分是物理磁盤上共享表空間連續(xù)的128個頁,大小也為2MB。在對緩沖池的臟頁進行刷新時,并不直接寫磁盤,而是通過memcpy函數(shù)將臟頁先復(fù)制到內(nèi)存中的該區(qū)域,之后通過doublewrite buffer再分兩次,每次1MB順序地寫入共享表空間的物理磁盤上,然后馬上調(diào)用fsync函數(shù),同步磁盤,避免操作系統(tǒng)緩沖寫帶來的問題。在完成doublewrite頁的寫入后,再講doublewirite buffer中的頁寫入各個表空間文件中。

?如果操作系統(tǒng)在將頁寫入磁盤的過程中發(fā)生了崩潰,在恢復(fù)過程中,InnoDB存儲引擎可以從共享表空間中的doublewrite中找到該頁的一個副本,將其復(fù)制到表空間文件中,再應(yīng)用重做日志。

 
重做日志(Redo Log Buffer)

?當(dāng)緩沖池中的頁的版本比磁盤要新時,數(shù)據(jù)庫需要將新版本的頁從緩沖池刷新到磁盤。但是如果每次一個頁發(fā)送變化,就進行刷新,那么性能開發(fā)是非常大的,于是InnoDB采用了Write Ahead Log策略,即當(dāng)事務(wù)提交時,先寫重做日志,然后再擇時將臟頁寫入磁盤。如果發(fā)生宕機導(dǎo)致數(shù)據(jù)丟失,就通過重做日志進行數(shù)據(jù)恢復(fù)。

InnoDB的內(nèi)存結(jié)構(gòu)及特性  
InnoDB數(shù)據(jù)寫入示意圖

?InnoDB存儲引擎會首先將重做日志信息先放入重做日志緩沖中,然后再按照一定頻率將其刷新到重做日志文件。重做日志緩沖一般不需要設(shè)置得很大,因為一般情況每一秒鐘都會講重做日志緩沖刷新到日志文件中??赏ㄟ^配置參數(shù)innodb_log_buffer_size控制,默認(rèn)為8MB。

?除了每秒刷新機制之外,每次事務(wù)提交時重做日志緩沖也會刷新到日志中。InnoDB是事務(wù)的存儲引擎,其通過Force Log at Commit機制實現(xiàn)事務(wù)的持久性,即當(dāng)事務(wù)提交時,必須先將該事務(wù)的所有日志寫入到重做日志文件進行持久化,然后事務(wù)的提交操作完成才算完成。InnoDB的寫入機制大致入下圖所示。

?為了確保每次日志都寫入到重做日志文件,在每次講重做日志緩沖寫入重做日志后,必須調(diào)用一次fsync操作,將緩沖文件從文件系統(tǒng)緩存中真正寫入磁盤。

?可以通過innodb_flush_log_at_trx_commit來控制重做日志刷新到磁盤的策略。該參數(shù)默認(rèn)值為1,表示事務(wù)提交必須進行一次fsync操作,還可以設(shè)置為0和2。0表示事務(wù)提交時不進行寫入重做日志操作,該操作只在主線程中完成,2表示提交時寫入重做日志,但是只寫入文件系統(tǒng)緩存,不進行fsync操作。由此可見,設(shè)置為0時,性能最高,但是喪失了事務(wù)的一致性。

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

?InnoDB會根據(jù)訪問的頻率和模式,為熱點頁建立哈希索引,來提高查詢效率。InnoDB存儲引擎會監(jiān)控對表上各個索引頁的查詢,如果觀察到建立哈希索引可以帶來速度上的提升,則建立哈希索引,所以叫做自適應(yīng)哈希索引。

?自適應(yīng)哈希索引是通過緩沖池的B+樹頁構(gòu)建而來,因此建立速度很快,而且不需要對整張數(shù)據(jù)表建立哈希索引。其有一個要求,即對這個頁的連續(xù)訪問模式必須是一樣的,也就是說其查詢的條件(WHERE)必須完全一樣,而且必須是連續(xù)的。

 
鎖信息(lock info)

?我們都知道,InnoDB存儲引擎會在行級別上對表數(shù)據(jù)進行上鎖。不過InnoDB也會在數(shù)據(jù)庫內(nèi)部其他很多地方使用鎖,從而允許對多種不同資源提供并發(fā)訪問。數(shù)據(jù)庫系統(tǒng)使用鎖是為了支持對共享資源進行并發(fā)訪問,提供數(shù)據(jù)的完整性和一致性。關(guān)于鎖的具體知識我們之后再進行詳細(xì)學(xué)習(xí)。

 
數(shù)據(jù)字典信息(Data Dictionary)

?InnoDB有自己的表緩存,可以稱為表定義緩存或者數(shù)據(jù)字典。當(dāng)InnoDB打開一張表,就增加一個對應(yīng)的對象到數(shù)據(jù)字典。

?數(shù)據(jù)字典是對數(shù)據(jù)庫中的數(shù)據(jù)、庫對象、表對象等的元信息的集合。在MySQL中,數(shù)據(jù)字典信息內(nèi)容就包括表結(jié)構(gòu)、數(shù)據(jù)庫名或表名、字段的數(shù)據(jù)類型、視圖、索引、表字段信息、存儲過程、觸發(fā)器等內(nèi)容。MySQL INFORMATION_SCHEMA庫提供了對數(shù)據(jù)局元數(shù)據(jù)、統(tǒng)計信息、以及有關(guān)MySQL server的訪問信息(例如:數(shù)據(jù)庫名或表名,字段的數(shù)據(jù)類型和訪問權(quán)限等)。該庫中保存的信息也可以稱為MySQL的數(shù)據(jù)字典。

 

“InnoDB的內(nèi)存結(jié)構(gòu)及特性”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實用文章!

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

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

AI