InnoDB體系架構(gòu)
InnoDB的存儲(chǔ)引擎體系結(jié)構(gòu)如下圖所示否灾,從圖中可知昌犹,InnoDB存儲(chǔ)引擎有多個(gè)內(nèi)存塊盏档,可以認(rèn)為這些內(nèi)存塊組成了一個(gè)大的內(nèi)存池般哼,負(fù)責(zé)如下工作:
1.維護(hù)所有進(jìn)程/線程需要訪問的多個(gè)內(nèi)存數(shù)據(jù)結(jié)構(gòu)
2.緩存磁盤上的數(shù)據(jù),方便快速地讀取钞楼,同時(shí)在對(duì)磁盤文件的數(shù)據(jù)修改之前在這里緩存
3.重做日志(redo log)緩沖
沽翔。。。
后臺(tái)線程
InnoDB存儲(chǔ)引擎是多線程的模型仅偎,因此后臺(tái)有多個(gè)不同的后臺(tái)線程跨蟹,負(fù)責(zé)處理不同的任務(wù)。
1.Master Thread
Master Thread主要負(fù)責(zé)將緩沖池中的數(shù)據(jù)異步刷新到磁盤橘沥,保證數(shù)據(jù)的一致性窗轩,包括臟頁(yè)的刷新,合并插入緩沖(INSERT BUFFER),UNDO頁(yè)的回收座咆。
2.IO Thread
在InnoDB存儲(chǔ)引擎中大量使用了AIO(Async IO)來(lái)處理寫IO請(qǐng)求型宙,這樣可以極大提高數(shù)據(jù)庫(kù)的性能距辆。IO Thread主要負(fù)責(zé)這些IO請(qǐng)求的回調(diào)處理公壤。從InnoDB 1.0.X版本開始踢京,一共有10個(gè)線程,4個(gè)read thread和4個(gè)write thread和insert buffer 和log IO thread哺呜。
可以通過show variables like 'innodb_version'查看innodb引擎版本號(hào)舌缤。
可以通過show variables like 'innodb_%_threads'查看線程數(shù)量。
可以通過show engine innodb status來(lái)觀察InnoDB中的IO Thread某残。
3.Purge Thread
事務(wù)被提交后国撵,其所使用的undolog可能不在需要,因此需要Purge Thread來(lái)回收已經(jīng)使用并分批的undo頁(yè)玻墅。從InnoDB 1.2開始介牙,支持多個(gè)Purge Thread,這樣做可以進(jìn)一步加快undo頁(yè)的回收澳厢。
可以在MySQL數(shù)據(jù)庫(kù)的配置文件中添加如下命令來(lái)啟用獨(dú)立的Purge Thread:
[mysqld]
innodb_purge_threads=1
4.Page Cleaner Thread
Page Cleaner Thread的作用是將之前版本中的臟頁(yè)的刷新操作都放入到單獨(dú)的線程中完成环础。其目的是對(duì)于用戶查詢線程的阻塞,進(jìn)一步提高存儲(chǔ)引擎新能剩拢。
內(nèi)存
1.緩沖池
InnoDB存儲(chǔ)引擎是基于磁盤存儲(chǔ)的线得。基于磁盤的數(shù)據(jù)庫(kù)通常使用緩沖池技術(shù)老提供數(shù)據(jù)庫(kù)的新能裸扶。緩沖池簡(jiǎn)單的來(lái)說就是一塊內(nèi)存區(qū)域框都,通過內(nèi)存的速度來(lái)彌補(bǔ)磁盤速度較慢對(duì)數(shù)據(jù)庫(kù)性能的影響搬素。
在數(shù)據(jù)庫(kù)中進(jìn)行讀取頁(yè)的操作時(shí)呵晨,首先將磁盤讀到的頁(yè)存放在緩沖池中,下一次在讀心相同頁(yè)時(shí)熬尺,首先判斷該頁(yè)是否在緩沖池中摸屠,若在,則稱該頁(yè)在緩沖池中被命中粱哼,直接讀取該頁(yè)季二。否則從磁盤上讀取。在數(shù)據(jù)庫(kù)中進(jìn)行修改頁(yè)操作時(shí),首先修改緩沖池中的頁(yè)胯舷,再以一定頻率刷到磁盤上刻蚯。頁(yè)從緩沖池刷新回磁盤的操作并不是每次更新時(shí)觸發(fā),而是通過Checkpoint的機(jī)制刷新回磁盤桑嘶。
綜上所述炊汹,緩沖池的大小直接影響數(shù)據(jù)庫(kù)的性能。由于32位系統(tǒng)的限制逃顶,強(qiáng)烈建議數(shù)據(jù)庫(kù)服務(wù)器采用64位操作系統(tǒng)讨便。可以通過innodb_buffer_pool_size來(lái)設(shè)置緩沖池大小以政,也可以通過innodb_buffer_pool_instances來(lái)配置多個(gè)緩沖池實(shí)例霸褒。
2.LRU List,Free List,Flush List
LRU List--數(shù)據(jù)庫(kù)緩沖池通過LRU(Last Recent Used,最近最少使用)算法進(jìn)行管理,緩沖池中的頁(yè)的大小默認(rèn)16KB盈蛮。InnoDB對(duì)傳統(tǒng)的LRU算法進(jìn)行了優(yōu)化废菱,加入了midpoint。傳統(tǒng)的LRU算法當(dāng)訪問到的頁(yè)不在緩沖區(qū)是直接將磁盤頁(yè)數(shù)據(jù)調(diào)到緩沖區(qū)隊(duì)列眉反;而InnoDB并不是直接插入到緩沖區(qū)隊(duì)列的隊(duì)頭昙啄,而是插入LRU列表的midpoint位置。這個(gè)算法稱之為midpoint insertion stategy寸五。默認(rèn)配置在列表長(zhǎng)度的5/8處梳凛。midpoint由參數(shù)innodb_old_blocks_pct控制。midpoint之前的列表稱之為new列表梳杏,之后的列表稱之為old列表韧拒。可以簡(jiǎn)單的將new列表中的頁(yè)理解為最為活躍的熱點(diǎn)數(shù)據(jù)十性。
Free List--數(shù)據(jù)庫(kù)剛啟動(dòng)時(shí)叛溢,LRU 列表為空。這時(shí)頁(yè)都存在Free列表中劲适,當(dāng)需要從緩沖池中分頁(yè)時(shí)楷掉,首先從Free列表中查找可用的空閑頁(yè),若有則將Free列表中的頁(yè)刪除霞势,放入LRU列表中烹植。否則根據(jù)LRU算法,淘汰LRU列表末尾頁(yè)愕贡,將改內(nèi)存空間分配給新的頁(yè)草雕。
Flush List--當(dāng)LRU列表中的頁(yè)被修改后,稱該頁(yè)為臟頁(yè)(dirty page)固以,即緩沖池中的頁(yè)和磁盤上的頁(yè)數(shù)據(jù)產(chǎn)生了不一致墩虹。這時(shí)候數(shù)據(jù)庫(kù)會(huì)通過checkpoint機(jī)制將臟頁(yè)刷新回磁盤嘱巾,而Flush 列表中的頁(yè)即為臟頁(yè)列表。注意臟頁(yè)即存在于LRU列表中,也存在Flush列表中诫钓。
3.重做日志緩沖
InnoDB存儲(chǔ)引擎先將重做日志信息放入重做日志緩沖區(qū)旬昭,然后按一定頻率將其刷新到重做日志文件。該值可以通過innodb_log_buffer_size控制菌湃,默認(rèn)8MB稳懒。一般情況下足以滿足絕大部分的應(yīng)用。
4.額外的內(nèi)存池
InnoDB存儲(chǔ)引擎中慢味,對(duì)內(nèi)存的管理是通過內(nèi)存堆的方式進(jìn)行的场梆。在對(duì)一些數(shù)據(jù)結(jié)構(gòu)本身的內(nèi)存進(jìn)行分配時(shí),需要從二娃的內(nèi)存池中申請(qǐng)纯路,當(dāng)該區(qū)域內(nèi)存不夠時(shí)或油,會(huì)從緩沖池中申請(qǐng)。
Checkpoint技術(shù)
Checkpoint技術(shù)的目的是解決如下幾個(gè)問題:
1.縮短數(shù)據(jù)庫(kù)的恢復(fù)時(shí)間
2.緩沖池不夠用時(shí)驰唬,將臟頁(yè)刷新到磁盤
3.重做日志不可用時(shí)顶岸,刷新臟頁(yè)
InnoDB存儲(chǔ)引擎中,有兩種Checkpoint:
1.Sharp Checkpoint--發(fā)生在數(shù)據(jù)庫(kù)關(guān)閉時(shí)將所有的臟頁(yè)都刷新會(huì)磁盤叫编,默認(rèn)的工作方式辖佣,即參數(shù)innodb_fast_shutdown=1
2.Fuzzy Checkpoint--數(shù)據(jù)庫(kù)運(yùn)行時(shí),刷新一部分臟頁(yè)回磁盤搓逾,而不是刷新所有臟頁(yè)回磁盤
Fuzzy Checkpoint又有如下幾種情況:
1.Master Thread Checkpoint --差不多以每秒或每十秒的速度從緩沖池的臟頁(yè)列表刷新一定比例的頁(yè)回磁盤卷谈,異步。
2.FLUSH_LRU_LIST Checkpoint --保證LRU列表中需要差不多100個(gè)空閑頁(yè)可以試用霞篡,5.6版本后可以通過innodb_lru_scan_depth控制LRU列表中可用頁(yè)的數(shù)量世蔗,5.6版本開始異步。
3.Async/Sync Flush Checkpoint --重做日志文件不可用的情況朗兵,需要強(qiáng)制將一些頁(yè)刷新回磁盤污淋,此時(shí)臟頁(yè)從臟頁(yè)列表中選取,5.6版本開始異步余掖。
4.Dirty Page too much --臟頁(yè)太多寸爆,引擎強(qiáng)制進(jìn)行checkpoint。目的是保證緩沖池有足夠可用的頁(yè)盐欺,可由參賽innodb_max_dirty_pages_pct控制赁豆,默認(rèn)75。
Master Thread工作方式
偽代碼和理解詳見書本找田,或以后單獨(dú)一章節(jié)記錄