日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Innodb结构

發(fā)布時(shí)間:2025/3/8 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Innodb结构 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

從MySQL5.5版本開始默認(rèn)使用InnoDB作為引擎,它擅長(zhǎng)處理事務(wù),具有自動(dòng)崩滿恢復(fù)的特性,在日常開發(fā)中使用非常廣泛,下面是言方的InnoDB引擎美構(gòu)圖,主要分為內(nèi)存結(jié)構(gòu)和磁盤結(jié)構(gòu)兩大部分。?

?內(nèi)存結(jié)構(gòu)主要包括Buffer Pool、Change Buffer、Adaptive Hash Index和Log Buffer四大組件。
Buffer Pool:緩沖池,簡(jiǎn)稱BP。BP以Page頁為單位,默認(rèn)大小16K,BP的底層采用鏈表數(shù)據(jù)結(jié)構(gòu)管理Page。在InnoDB訪問表記錄和索引時(shí)會(huì)在Page頁中緩存,以后使用可以減少磁盤IO操作,提升效率。

緩沖池簡(jiǎn)單來說就是一塊內(nèi)存區(qū)域,通過內(nèi)存的速度來彌補(bǔ)磁盤速度較慢對(duì)數(shù)據(jù)庫性能的影響。在數(shù)據(jù)庫中進(jìn)行讀取頁的操作,首先將從磁盤讀到的頁存放在緩沖池中,這個(gè)過程稱為將頁"FIX"在緩沖池中。下一次再讀取相同的頁時(shí),首先判斷該頁是否在緩沖池中。若在緩沖池中,稱該頁在緩沖池中被命中。直接讀取該頁。否則讀取磁盤上的頁。對(duì)于數(shù)據(jù)庫中頁的修改操作,則首先修改在緩沖池中的頁,然后再以一定的頻率刷新到磁盤上。這里需要注意的是,頁從緩沖池刷新回磁盤的操作并不是每次頁發(fā)生更新時(shí)觸發(fā),而是通過一種稱為Checkpoint的機(jī)制刷新回磁盤。同樣這也是為了提高數(shù)據(jù)庫的整體性能。

對(duì)于innodb存儲(chǔ)引擎而言,其緩沖池的配置通過參數(shù)innodb_buffer_ pool_size來設(shè)置。這是影響innodb性能的關(guān)鍵參數(shù)。具體來看,緩沖池中緩存的數(shù)據(jù)頁類型有:索引頁,數(shù)據(jù)頁,undo頁,插入緩沖(insert buffer),自適應(yīng)哈希索引(adaptive hash index),innodb存儲(chǔ)的鎖信息(lock info),數(shù)據(jù)字典信息(data dictionary)等。不能簡(jiǎn)單的認(rèn)為,緩沖池只是緩存索引頁和數(shù)據(jù)頁,它們只是占緩沖池很大的一部分而已。

Page管理機(jī)制
? Page根據(jù)狀態(tài)可以分為三種類型:
? ? ?·free page:空閑page,未被使用
? ? ?·clean page:被使用page,數(shù)據(jù)沒有被修改過
? ? ?·dirty page:臟頁,被使用page,數(shù)據(jù)被修改過,頁中數(shù)據(jù)和磁盤的數(shù)據(jù)產(chǎn)生了不一致

針對(duì)上述三種page類型,InnoDB通過三種鏈表結(jié)構(gòu)來維護(hù)和管理
? ? ·free list:表示空閑緩沖區(qū),管理free page
? ? ·flush list:表示需要刷新到磁盤的緩沖區(qū),管理dirty page,內(nèi)部page按修改時(shí)間排序。臟頁即? ? ? ? ? ? ? ? ? ? ? ?存在你flush鏈表,也在LRU鏈表中,但是兩種互不影響,LRU鏈表負(fù)責(zé)管理page的? ? ? ? ? ? ? ? ? ? ? ? ?可用性和釋放,而flush鏈表負(fù)責(zé)管理臟頁的刷盤操作。
? ? ·Iru list:表示正在使用的緩沖區(qū),管理clean page和dirty page,緩沖區(qū)以midpoint為基點(diǎn),前? ? ? ? ? ? ? ? ? ? ? 面鏈表稱為new列表區(qū),存放經(jīng)常訪問的數(shù)據(jù),占63%;后面的鏈表稱為old列表區(qū),? ? ? ? ? ? ? ? ? ? ? 存放使用較少數(shù)據(jù),占37%。
改進(jìn)型LRU算法維護(hù)
? ? 普通LRU:未尾淘汰法,新數(shù)據(jù)從鏈表頭部加入,釋放空間時(shí)從未尾淘汰
? ? 改性LRU:鏈表分為new和old兩個(gè)部分,加入元素時(shí)并不是從表頭插入,而是從中間midpoint? ? ? ? ? ? ? ? ? ? ? ? ?位置插入,如果數(shù)據(jù)很快被訪問,那么page就會(huì)向new列表頭部移動(dòng),如果數(shù)據(jù)沒? ? ? ? ? ? ? ? ? ? ? ? ?有被訪問,會(huì)逐步向old尾部移動(dòng),等待淘汰。

? ? ? ? ? ? ? ? ? ? ?每當(dāng)有新的page數(shù)據(jù)讀取到buffer pool時(shí),InnoDb引擎會(huì)判斷是否有空閑頁,是否? ? ? ? ? ? ? ? ? ? ? ? ?足夠,如果有就將free page從free list列表刪除,放入到LRU列表中。沒有空閑頁,? ? ? ? ? ? ? ? ? ? ? ? 就會(huì)根據(jù)LRU算法淘汰LRU鏈表默認(rèn)的頁,將內(nèi)存空間釋放分配給新的頁。

BUffer pool配置參數(shù):

show variables like%innodb_page_size%;/查看page頁大小

show variables like 9%innodb_old%;//查看ru list中old列表參數(shù)

show variables like9%innodb_buffer%;//查看buffer pool參數(shù)

建議:將innodb_buffer_pool_size設(shè)置為總內(nèi)存的60%-80%,innodb_buffer_pool_instances可以設(shè)置為多個(gè),這樣可以避免緩存爭(zhēng)奪。|

從innodb1.0.x版本開始,允許有多個(gè)緩沖池實(shí)例。每個(gè)頁根據(jù)哈希值平均分配到不同緩沖池實(shí)例中。這樣做的好處是減少數(shù)據(jù)庫內(nèi)部的資源競(jìng)爭(zhēng)。增加數(shù)據(jù)庫的并發(fā)處理能力。通過參數(shù)innodb_buffer_pool_instances來進(jìn)行配置。該值默認(rèn)為1。在配置文件中將innodb_buffer_pool_instances設(shè)置為大于1的值就可以得到多個(gè)緩沖池實(shí)例。

注意:innodb_buffer_pool_size必須大于1GB,生成innodb_buffer_pool多實(shí)例才有效,最多支持64個(gè)innodb_buffer_pool實(shí)例。

?Change Buffer:寫緩沖區(qū),簡(jiǎn)稱CB。在進(jìn)行DML操作時(shí),如果BP沒有其相應(yīng)的Page數(shù)據(jù),并不會(huì)立刻將磁盤頁加載到緩沖池,而是在CB記錄緩沖變更,等未來數(shù)據(jù)被讀取時(shí),再將數(shù)據(jù)合并恢復(fù)到BP中。
ChangeBuffer占用BufferPool空間,默認(rèn)占25%,最大允許占50%,可以根據(jù)讀寫業(yè)務(wù)量來進(jìn)行調(diào)整。
參數(shù)innodb_change_buffer_max size;當(dāng)更新一條記錄時(shí),該記錄在BufferPool存在,直接在BufferPool修改,一次內(nèi)存操作。如果該記錄在BufferPool不存在(沒有命中),會(huì)直接在ChangeBuffer進(jìn)行一次內(nèi)存操作,不用再去磁盤查詢數(shù)據(jù),避免一次磁盤1O。當(dāng)下次查詢記錄時(shí),會(huì)先進(jìn)性磁盤讀取,然后再從ChangeBuffer中讀取信息合并,最終載入BufferPool中。
寫緩沖區(qū),僅適用于非準(zhǔn)一普通索引頁,為什么?
如果在索引設(shè)置唯一性,在進(jìn)行修改時(shí),InnoDB必須要做唯一性校驗(yàn),因此必須查詢磁盤,做一次I0操作。會(huì)直接將記錄查詢到BufferPool中,然后在緩沖池修改,不會(huì)在ChangeBufer操作。

Adaptive Hash Index:自適應(yīng)哈希索引,用于優(yōu)化對(duì)BP數(shù)據(jù)的查詢。InnoDB存儲(chǔ)引擎會(huì)監(jiān)控對(duì)表索引的查找,如果觀察到建立哈希索引可以帶來速度的提升,則建立哈希索引,所以稱之為自適應(yīng)。InnoDB存儲(chǔ)引擎會(huì)自動(dòng)根據(jù)訪問的頻率和模式來為某些頁建立哈希索引。
Log Bufer:日志緩沖區(qū),用來保存要寫入磁盤上log文件(Redo/Undo)的數(shù)據(jù),日志緩沖區(qū)的內(nèi)容定期刷新到磁盤log文件中。日志緩沖區(qū)滿時(shí)會(huì)自動(dòng)將其刷新到磁盤,當(dāng)遇到BLOB或多行更新的大事務(wù)操作時(shí),增加日志緩沖區(qū)可以節(jié)省磁盤/O。
LogBuffer主要是用于記錄InnoDB引擎日志,在DML操作時(shí)會(huì)產(chǎn)生Redo和Undo日志。
LogBuffer空間滿了,會(huì)自動(dòng)寫入磁盤。
innodb_flush_log at trxrcommit參數(shù)控制日志刷新行為,默認(rèn)為1
? 0:每隔1秒寫日志文件和刷盤操作(寫日志文件LogBuffer->oS cache,刷盤OS cache->磁盤文? ? ? ? ? 件),最多丟失1秒數(shù)據(jù)
?1:事務(wù)提交,立刻寫日志文件和刷盤,數(shù)據(jù)不丟失,但是會(huì)頻繁10操作
?2:事務(wù)提交,立刻寫日志文件,每隔1秒鐘進(jìn)行刷盤操伸

從上圖大致可以看到innodb有多個(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)線程的主要作用是負(fù)責(zé)刷新內(nèi)存池中的數(shù)據(jù),保證緩沖池中的內(nèi)存緩存的是最新最近的數(shù)據(jù)。此外將已經(jīng)修改的數(shù)據(jù)文件刷新到磁盤文件,同時(shí)保證在數(shù)據(jù)庫發(fā)生異常的情況下innodb能恢復(fù)正常的運(yùn)行狀態(tài)。

后臺(tái)線程:

Innodb存儲(chǔ)引擎是多線程的模型,因此其后臺(tái)有多個(gè)不同的后臺(tái)線程,負(fù)責(zé)處理不同的任務(wù)。

1.Master Thread

Master Thread 是非常核心的后臺(tái)線程,主要負(fù)責(zé)將緩沖池中的數(shù)據(jù)異步刷新到磁盤,保證數(shù)據(jù)的一致性,包括臟頁的刷新,合并插入緩沖(insert buffer),undo頁的回收等。

2.IO Thread

在innodb存儲(chǔ)引擎中大量使用了AIO(Async IO)來處理寫IO請(qǐng)求,這樣可以極大提高數(shù)據(jù)庫的性能。而IO Thread的工作主要負(fù)責(zé)這些IO請(qǐng)求的回調(diào)(call back)處理。在innodb 1.0版本之前共有4個(gè)IO Thread,分別是write,read,insert buffer和log IO thread。從innodb 1.0.x版本開始,read thread和write thread分別增大到了4個(gè)。可以使用innodb_read_io_threads和innodb_write_io_threads參數(shù)進(jìn)行設(shè)置。

3. Purge Thread

事務(wù)被提交后,其使用的undo log可能不再需要,因此Purge Thread來回收已經(jīng)使用并分配的undo頁。在innodb 1.1 版本之前,purge操作僅在innodb存儲(chǔ)引擎的Master Thread中完成。從innodb1.1版本開始,purge操作可以獨(dú)立到單獨(dú)的線程中進(jìn)行。以此來減輕Master Thread的工作。從而提高CPU的使用率以及提升存儲(chǔ)引擎的性能。可以通過在配置文件中添加如下參數(shù)來開啟獨(dú)立的Purge Thread(清洗線程)

?在innodb1.1版本中,即使innodb_purge_threads設(shè)為大于1,innodb存儲(chǔ)引擎啟動(dòng)時(shí)也會(huì)將其設(shè)為1,從innodb1.2版本開始,innodb支持多個(gè)Purge Thread,這樣做的目的是為了進(jìn)一步加快undo頁的回收。同時(shí)由于Purge Thread需要離散的讀取undo頁,這樣可以更好的利用磁盤的隨機(jī)讀取性能。

4.Page cleaner Thread

page cleaner thread線程是在innodb 1.2.x的版本中引入的。其作用是將之前的版本中的臟頁刷新操作都放入到單獨(dú)的線程中來完成。而其目的是為了減輕原Master Thread的工作及對(duì)于用戶查詢線程的阻塞,進(jìn)一步提高innodb存儲(chǔ)引擎的性能。

總結(jié)

以上是生活随笔為你收集整理的Innodb结构的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。