InnoDB是在MySQL存儲(chǔ)引擎中第一個(gè)完整支持ACID事務(wù)的引擎,該引擎之前由Innobase OY公司所開(kāi)發(fā),后來(lái)該公司被Oracle收購(gòu)。InnoDB是MySQL數(shù)據(jù)庫(kù)中使用最廣泛的存儲(chǔ)引擎,已被許多大型公司所采用,如Google、Facebook、YouTube等,如果使用MySQL數(shù)據(jù)庫(kù)服務(wù),沒(méi)有特殊的要求下,InnoDB是不二之選。
1.InnoDB體系架構(gòu)
需要深入了解InnoDB先從了解InnoDB的體系架構(gòu)開(kāi)始,如下圖所示:
InnoDB存儲(chǔ)引擎有多個(gè)內(nèi)存塊,可以認(rèn)為這些內(nèi)存塊組成了一個(gè)大的內(nèi)存池,負(fù)責(zé)以下幾個(gè)工作:
維護(hù)所有進(jìn)程/線程,需要訪問(wèn)的多個(gè)內(nèi)部數(shù)據(jù)結(jié)構(gòu);
緩存磁盤(pán)上的數(shù)據(jù),方便快速地讀取,同時(shí)在對(duì)磁盤(pán)文件的數(shù)據(jù)修改之前在這里緩存;
重做日志(redo log)緩沖(簡(jiǎn)單來(lái)講,redo log記錄的是事務(wù)所對(duì)應(yīng)的數(shù)據(jù)更新日志,用于降低每次數(shù)據(jù)變更都產(chǎn)生的磁盤(pán)IO,該日志由工作線程定時(shí)把數(shù)據(jù)的更新內(nèi)容定時(shí)刷新到磁盤(pán)中去,當(dāng)數(shù)據(jù)庫(kù)奔潰時(shí)數(shù)據(jù)還沒(méi)來(lái)得及刷新到磁盤(pán),重新啟動(dòng)運(yùn)行是則可以從redo log里面重新提取刷新到磁盤(pán),具體有關(guān)redo log在后面相關(guān)章節(jié)會(huì)詳細(xì)介紹)。
后臺(tái)線程的主要作用是負(fù)責(zé)刷新內(nèi)存池中的數(shù)據(jù),保證緩沖池中的內(nèi)存緩沖的是最近的數(shù)據(jù),此外除將已修改的數(shù)據(jù)文件刷新到磁盤(pán)中,同時(shí)保證在數(shù)據(jù)庫(kù)發(fā)生異常的情況下InnoDB能恢復(fù)到正常運(yùn)行狀態(tài)。
2.后臺(tái)線程
master thread
master thread是一個(gè)非常核心的后臺(tái)線程,主要負(fù)責(zé)將緩沖池中的數(shù)據(jù)異步刷新到磁盤(pán),保證數(shù)據(jù)的一致性,包括臟頁(yè)面的刷新、合并插入緩沖、undo頁(yè)的回收等。
io thread
在InnoDB引擎中大量使用了AIO(Async IO)來(lái)處理寫(xiě)IO請(qǐng)求,這樣可以極大提高數(shù)據(jù)庫(kù)的性能。而io thread的主要工作就是負(fù)責(zé)這些IO請(qǐng)求的回調(diào)處理。可以使用命令show engine innodb status\G
來(lái)觀察io threa。
圖片來(lái)自廣東睿江云
從上圖可以看到,有1個(gè)insert buffer線程;1個(gè)log線程;4個(gè)read線程;4個(gè)write線程。
purge thread
事務(wù)被提交后,其所使用的undo log(用于事務(wù)commit失敗后回滾操作用)可能不在需要,因此需要purge線程來(lái)回收undo頁(yè)。在InnoDB 1.1版本之前,purge thread在master thread中完成;而從InnoDB 1.1版本開(kāi)始,purge操作獨(dú)立到專(zhuān)門(mén)的線程執(zhí)行,以減輕master thread壓力,提升cpu使用率、提升引擎性能;從InnoDB 1.2版本開(kāi)始,還支持多個(gè)purge thread以進(jìn)一步加快undo頁(yè)回收。
page cleaner thread
在InnoDB 1.2.x版本中引入,其作用是將之前版本中臟頁(yè)面是刷新操作都放在獨(dú)立的線程中完成,也是為了減輕master thread的壓力,提升性能。
3.內(nèi)存
緩沖池
InnoDB引擎的數(shù)據(jù)存儲(chǔ)是基于磁盤(pán)的,把記錄按照一定的格式記錄在磁盤(pán),但是由于CPU與磁盤(pán)的速度有較大的差別,因此引入了基于內(nèi)存緩沖技術(shù)來(lái)提高數(shù)據(jù)庫(kù)的性能。簡(jiǎn)單來(lái)講,把要讀取數(shù)據(jù)的磁盤(pán)內(nèi)容先加載到內(nèi)存緩沖區(qū)域,下次讀取同樣數(shù)據(jù)時(shí)先判斷是否被緩沖區(qū)所緩存,如果緩存則從緩沖區(qū)讀取內(nèi)容;同樣,當(dāng)需要對(duì)數(shù)據(jù)進(jìn)行修改時(shí),不直接修改磁盤(pán)對(duì)應(yīng)數(shù)據(jù),而是先修改緩沖區(qū)域,然后通過(guò)一種叫checkpoint(具體后面會(huì)介紹)的機(jī)制把更新的數(shù)據(jù)刷新到磁盤(pán)。
因此對(duì)于InnoDB引擎來(lái)講,緩沖池的設(shè)置變得尤其重要,可以通過(guò)innodb_buffer_pool_size參數(shù)進(jìn)行設(shè)置。
雖然緩沖池是為了緩沖數(shù)據(jù),但是緩沖池保存的數(shù)據(jù)類(lèi)型不僅僅只有數(shù)據(jù)庫(kù)的記錄,有以下幾種類(lèi)型:索引頁(yè)、數(shù)據(jù)頁(yè)、undo頁(yè)、插入緩沖(insert buffer)、自適應(yīng)哈希索引、InnoDB存儲(chǔ)的鎖信息(lock info)、數(shù)據(jù)字典信息等。
從InnoDB 1.0.x版本開(kāi)始,允許有多個(gè)緩沖池實(shí)例,每個(gè)頁(yè)根據(jù)哈希值平均分配到不同緩沖池實(shí)例中,這樣可以增加數(shù)據(jù)庫(kù)的并發(fā)處理。具體多實(shí)例緩沖池本文不再詳細(xì)展開(kāi)描述,有興趣者可以繼續(xù)通過(guò)其它途徑深入了解。
內(nèi)存管理 LRU List、Free List、Flush List
通常來(lái)說(shuō),數(shù)據(jù)庫(kù)中的內(nèi)存緩沖區(qū)是通過(guò)LRU(Latest Recent Used,最近最少使用)算法來(lái)進(jìn)行管理。即頻繁使用的頁(yè)在LRU列表的前端,而最少使用的頁(yè)在LRU的尾端。當(dāng)緩沖池不能存放新讀取到的頁(yè)時(shí),將首先釋放LRU列表尾端的頁(yè)。
在InnoDB引擎中,緩沖池中頁(yè)的大小默認(rèn)是16KB,同樣也是使用LRU算法來(lái)進(jìn)行管理,稍有不同的是,引擎對(duì)傳統(tǒng)的LRU算法進(jìn)行了一些優(yōu)化,當(dāng)讀取到新的頁(yè),但并不是直接插入到LRU列表的首部,而是插入到LRU列表的midpoint位置,這個(gè)位置可以通過(guò)參數(shù)innodb_old_blocks_pct控制,默認(rèn)情況下這個(gè)數(shù)值是37,代表插入到LRU列表尾部的37%的位置。關(guān)于InnoDB下LRU的算法不在本文詳細(xì)講解,有興趣的讀者可以自行查閱相關(guān)資料。
介紹完LRU List,下面介紹Free List,F(xiàn)ree列表保存的是空閑頁(yè),引擎需要從緩沖池中分頁(yè)時(shí),首先從Free列表中查找是否有空閑頁(yè),若有則把頁(yè)從Free List獲取然后刪除放到LRU List中,同理當(dāng)LRU List的頁(yè)面需要淘汰時(shí)則重新加入到Free List。
在LRU列表中的頁(yè)被修改后,程該頁(yè)為臟頁(yè)(dirty page),即緩沖池中的頁(yè)和磁盤(pán)上的頁(yè)數(shù)據(jù)產(chǎn)生了不一致,這時(shí)候數(shù)據(jù)庫(kù)會(huì)通過(guò)checkpoint機(jī)制將臟頁(yè)刷新回磁盤(pán)(關(guān)于checkpoint在下一節(jié)會(huì)介紹),而Flush List則是專(zhuān)門(mén)保存這些臟頁(yè)的列表。
redo log重做日志
InnoDB存儲(chǔ)引擎的內(nèi)存區(qū)域除了緩沖池外,還有重做日志緩沖(redo log buffer)。InnoDB存儲(chǔ)引擎首先將日志信息先放入到這個(gè)緩沖區(qū),然后按一定的頻率刷新到redo log文件中。在后面“文件”一章會(huì)詳細(xì)描述各自文件及其作用,其中就包含了redo log,這里先不做過(guò)多的講解。
額外的內(nèi)存池
額外的內(nèi)存池記錄的是數(shù)據(jù)庫(kù)內(nèi)部需要用到的各種數(shù)據(jù)結(jié)構(gòu),比如記錄緩沖池信息的、記錄LRU、鎖等,這塊往往也會(huì)被忽略。
4.checkpoint
在前面的小結(jié)描述過(guò),緩沖池設(shè)計(jì)的目的是為了協(xié)調(diào)CPU速度與磁盤(pán)速度的鴻溝,頁(yè)的所有操作首先都是在緩沖池中完成的,如一條update、delete、insert語(yǔ)句改變了頁(yè)中的記錄,那么此時(shí)此頁(yè)是臟的,數(shù)據(jù)庫(kù)需要把頁(yè)的數(shù)據(jù)更新到磁盤(pán)中。
如果每一次變化都立刻更新到磁盤(pán),那么這個(gè)效率會(huì)非常大,也失去了緩沖池的意義,但是如果長(zhǎng)時(shí)間不刷新又會(huì)導(dǎo)致數(shù)據(jù)庫(kù)崩潰時(shí)刻無(wú)法及時(shí)把數(shù)據(jù)更新到磁盤(pán)而出現(xiàn)數(shù)據(jù)的不一致性。
為了避免這些問(wèn)題,當(dāng)前事務(wù)型的數(shù)據(jù)庫(kù)普遍都采用了wirte ahead log的策略,即當(dāng)事務(wù)提交的時(shí)候,先寫(xiě)redo log,再修改頁(yè),如果期間發(fā)生宕機(jī)了可以通過(guò)redo log進(jìn)行數(shù)據(jù)恢復(fù)。
checkpoint技術(shù)就是用于記錄redo log里面,那些log已經(jīng)刷新到磁盤(pán)了,那些log還沒(méi)刷新,在InnoDB引擎里面,其checkpoint標(biāo)記是通過(guò)一個(gè)叫LSN(log sequence number)來(lái)標(biāo)記,LSN是一個(gè)8字節(jié)的數(shù)字,LSN之前的log都是已經(jīng)被刷新到磁盤(pán)了,之后都是未被刷新的,所以當(dāng)數(shù)據(jù)庫(kù)宕機(jī)恢復(fù)的時(shí)候,只需要把LSN之后的redo log進(jìn)行刷新即可。
5.InnoDB關(guān)鍵特性
InnoDB存儲(chǔ)引擎的關(guān)鍵特性包括:
插入緩沖(insert buffer)
兩次寫(xiě)(double write)
自適應(yīng)哈希索引(adaptive hash index)
異步io(async io)
刷新鄰接頁(yè)(flush neighbor page)
下面只選取其中一些比較好理解的特性來(lái)簡(jiǎn)單介紹,其他比較復(fù)雜的如插入緩沖、自適應(yīng)哈希索引留待讀者自行去做詳細(xì)的研究。
兩次寫(xiě)
顧名思義,就是寫(xiě)兩次的意思,在InnoDB引擎中,有個(gè)叫共享表空間,這個(gè)空間可以存放一些共享的數(shù)據(jù),比如索引等信息,當(dāng)數(shù)據(jù)庫(kù)需要把一個(gè)緩沖池的頁(yè)刷新到磁盤(pán)時(shí),先把頁(yè)數(shù)據(jù)寫(xiě)入到共享表空間,然后再寫(xiě)入磁盤(pán),當(dāng)寫(xiě)入磁盤(pán)發(fā)現(xiàn)異常導(dǎo)致數(shù)據(jù)丟失了,這時(shí)候從共享表空間把數(shù)據(jù)恢復(fù)重新寫(xiě)入磁盤(pán)。
異步io
簡(jiǎn)單來(lái)講,異步io就是把io操作變成異步的方式,比如需要對(duì)磁盤(pán)進(jìn)行讀寫(xiě),則先發(fā)起一個(gè)io操作,等待磁盤(pán)讀寫(xiě)完成后再通知上層進(jìn)行處理,異步io還有一個(gè)好處是可以對(duì)一些io操作進(jìn)行合并優(yōu)化,比如可以對(duì)連續(xù)頁(yè)的請(qǐng)求進(jìn)行合并成一次請(qǐng)求等。
刷新鄰接頁(yè)
這個(gè)也是比較好理解的,就是當(dāng)刷新一個(gè)臟頁(yè)時(shí),InnoDB存儲(chǔ)引擎會(huì)檢測(cè)該頁(yè)所在的區(qū)的所有頁(yè),如果都是臟頁(yè),那么一起進(jìn)行刷新,可以借助異步io進(jìn)行多個(gè)寫(xiě)操作的合并,提升效率。
另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)cdcxhl.cn,海內(nèi)外云服務(wù)器15元起步,三天無(wú)理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國(guó)服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡(jiǎn)單易用、服務(wù)可用性高、性?xún)r(jià)比高”等特點(diǎn)與優(yōu)勢(shì),專(zhuān)為企業(yè)上云打造定制,能夠滿(mǎn)足用戶(hù)豐富、多元化的應(yīng)用場(chǎng)景需求。
當(dāng)前名稱(chēng):InnoDB存儲(chǔ)引擎-創(chuàng)新互聯(lián)
瀏覽路徑:http://jinyejixie.com/article40/gjheo.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站設(shè)計(jì)、網(wǎng)站策劃、網(wǎng)站改版、面包屑導(dǎo)航、營(yíng)銷(xiāo)型網(wǎng)站建設(shè)、網(wǎng)站維護(hù)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(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)
猜你還喜歡下面的內(nèi)容