日本黄色一级经典视频|伊人久久精品视频|亚洲黄色色周成人视频九九九|av免费网址黄色小短片|黄色Av无码亚洲成年人|亚洲1区2区3区无码|真人黄片免费观看|无码一级小说欧美日免费三级|日韩中文字幕91在线看|精品久久久无码中文字幕边打电话

當(dāng)前位置:首頁 > > 架構(gòu)師社區(qū)
[導(dǎo)讀]今天來聊一聊 Mysql 緩存池原理。

今天來聊一聊 Mysql 緩存池原理。

提綱附上,話不多說,直接干貨。

面試官:能說一說Mysql緩存池嗎?

前言

面試官:同學(xué),你能說說Mysql 緩存池嗎?

狂聊君:啊,這么難嗎,容我組織一下語言。(內(nèi)心OS:這TM還不簡單?我能給你扯半小時!

面試官:可以,給你一分鐘時間想一想吧。

....一分鐘后....

狂聊君:我準(zhǔn)備好了,你可聽好,我要開始表演了。

為什么要有緩存池?

Mysql 的 innodb 存儲引擎是基于磁盤存儲的,并且是按照頁的方式進(jìn)行管理的。

在數(shù)據(jù)庫系統(tǒng)中,CPU 速度與磁盤速度之間的差距是非常大的,為了最大可能的彌補(bǔ)之間的差距,提出了緩存池的概念。

所以緩存池,簡單來說就是一塊「內(nèi)存區(qū)域」,通過內(nèi)存的速度來彌補(bǔ)磁盤速度較慢,導(dǎo)致對數(shù)據(jù)庫造成性能的影響。

緩存池的基本原理

「讀操作」:

在數(shù)據(jù)庫中進(jìn)行讀取頁的操作,首先把從磁盤讀到的頁存放在緩存池中,下一次讀取相同的頁時,首先判斷該頁是不是在緩存池中。

若在,稱該頁在緩存池中被命中,則直接讀取該頁,否則,還是去讀取磁盤上的頁。

「寫操作」:

對于數(shù)據(jù)庫中頁的修改操作,首先修改在緩存池中的頁,然后在以一定的頻率刷新到磁盤,并不是每次頁發(fā)生改變就刷新回磁盤,而是通過 checkpoint 的機(jī)制把頁刷新回磁盤。

可以看到,無論是讀操作還是寫操縱,都是對緩存池進(jìn)行操作,而不是直接對磁盤進(jìn)行操縱。

緩存池結(jié)構(gòu)

Buffer Pool 是一片連續(xù)的內(nèi)存空間,innodb 存儲引擎是通過頁的方式對這塊內(nèi)存進(jìn)行管理的。

緩存池的結(jié)構(gòu)如下圖:

面試官:能說一說Mysql緩存池嗎?

可以看到緩存池中包括數(shù)據(jù)頁、索引頁、插入緩存、自適應(yīng)哈希索引、鎖信息、數(shù)據(jù)字段。

其中數(shù)據(jù)頁和索引頁會用掉多數(shù)內(nèi)存。

「但是,innodb 是如何管理緩存池中的這么多頁呢?」

為了更好的管理這些緩存的頁,innodb 為每一個緩存頁都創(chuàng)建了一些所謂的控制信息,這些控制信息包括該頁所屬的:

  • 表空間編號(sapce id)
  • 頁號(page numeber)
  • 頁在 buffer Pool 的地址
  • 一些鎖信息以及 LSN 信息日志序列號
  • 其他控制信息

每個緩存頁對應(yīng)的控制信息占用的內(nèi)存大小是相同的,我們把每個頁對應(yīng)的控制信息占用的一塊內(nèi)存稱為一個「控制塊」。

「控制塊」和緩存頁是一一對應(yīng)的,它們都被存放到 Buffer Pool 中,其中控制塊被存放到 Buffer Pool 的前邊,緩存頁被存放到 Buffer Pool 的后邊。

Buffer Pool 對應(yīng)的內(nèi)存空間示意圖:

面試官:能說一說Mysql緩存池嗎?

緩存池參數(shù)設(shè)置

  • innodb_buffer_pool_size:緩存池的大小最多應(yīng)設(shè)置為物理內(nèi)存的 80%
  • innodb_buffer_pool_instance:設(shè)置有多少個緩存池,通常建議把緩存池個數(shù)設(shè)置為 CPU 的個數(shù),多個緩存池可以減少數(shù)據(jù)庫內(nèi)部的資源競爭,增加數(shù)據(jù)庫并發(fā)訪問的能力
  • innodb_old_blocks_pct:老生代占整個 LRU 的鏈長比例,默認(rèn)是 3:7
  • innodb_old_blocks_time:老生代停留時間窗口,單位是毫秒,默認(rèn)是 1000,即同時滿足“被訪問”與“在老生代停留時間超過 1 秒”兩個條件,才會被插入到新生代頭部

緩存池管理

「管理緩存池依賴的鏈表結(jié)構(gòu)」:

Free 鏈表

當(dāng)啟動 Mysql 服務(wù)器的時候,需要完成對 Buffer Pool 的初始化過程,即分配 Buffer Pool 的內(nèi)存空間,把它劃分為若干對控制塊和緩存頁,但是此時并沒有真正的磁盤頁被緩存到 Buffer Pool 中,之后隨著程序的運(yùn)行,會不斷的有磁盤上的頁被緩存到 Buffer Pool 中。

在使用過程中,為了記錄哪些緩存頁是可用的,我們把所有空閑的頁包裝成一個節(jié)點(diǎn)組成一個鏈表,這個鏈表可以稱作為 Free 鏈表(空閑鏈表)。因為剛剛完成初始化的 Buffer Pool 中所有的緩存頁都是空閑的,所以每一個緩存頁都會被加入到 Free 鏈表中。

為了方便管理 Free 鏈表,特意為這個鏈表定義了一些「控制信息」,里面包含鏈表的頭節(jié)點(diǎn)地址,尾節(jié)點(diǎn)地址,以及當(dāng)前鏈表中節(jié)點(diǎn)的數(shù)量等信息。

另外會在每個 Free 鏈表的節(jié)點(diǎn)中都記錄了某個「緩存頁控制塊」的地址,而每個「緩存頁控制塊」都記錄著對應(yīng)的「緩存頁地址」,所以相當(dāng)于每個 Free 鏈表節(jié)點(diǎn)都對應(yīng)一個空閑的緩存頁。

給大家畫了個結(jié)構(gòu)圖:

面試官:能說一說Mysql緩存池嗎?

這圖怎么樣,這下能看的懂了吧!

2、Lru 鏈表

Lru 鏈表用來管理已經(jīng)讀取的頁,當(dāng)數(shù)據(jù)庫剛啟動時,Lru 鏈表是空的,此時頁也都放在 Free 列表中,當(dāng)需要讀取數(shù)據(jù)時,會從 Free 鏈表中申請一個頁,把從放入到磁盤讀取的數(shù)據(jù)放入到申請的頁中,這個頁的集合叫做 Lru 鏈表。

3、Flush 鏈表

Flush 鏈表用來管理被修改的頁,Buffer Pool 中被修改的頁也被稱之為「臟頁」,臟頁既存在于 Lru 鏈表中,也存在于 Flush 鏈表中,F(xiàn)lush 鏈表中存的是一個指向 Lru 鏈表中具體數(shù)據(jù)的指針。

因此只有 Lru 鏈表中的頁第一次被修改時,對應(yīng)的指針才會存入到 Flush 中,若之后再修改這個頁,則是直接更新 Lru 鏈表中的頁對應(yīng)的數(shù)據(jù)。

這三者之間是這么個關(guān)系:

面試官:能說一說Mysql緩存池嗎?

讀操作

Buffer Pool 一個最主要的功能是「加速讀」。加速讀是當(dāng)需要訪問一個數(shù)據(jù)頁面的時候,如果這個頁面已經(jīng)在緩存池中,那么就不再需要訪問磁盤,直接從緩沖池中就能獲取這個頁面的內(nèi)容。當(dāng)我們需要訪問某個頁中的數(shù)據(jù)時,就會把該頁加載到 Buffer Pool 中,如果該頁已經(jīng)在 Buffer Pool 中的話直接使用就可以了。

問題:那么如何快速查找在 Buffer Pool 中的頁呢?

為了避免查詢數(shù)據(jù)頁時掃描 Lru,其實是根據(jù)表空間號 + 頁號來定位一個頁的,也就相當(dāng)于表空間號 + 頁號是一個 key,緩存頁就是對應(yīng)的 value。用表空間號 + 頁號作為 key,緩存頁作為 value 創(chuàng)建一個哈希表,在需要訪問某個頁的數(shù)據(jù)時,先從哈希表中根據(jù)表空間號 + 頁號看看有沒有對應(yīng)的緩存頁。

如果有,直接使用該緩存頁就好。

如果沒有,那就從 Free 鏈表中選一個空閑的緩存頁,然后把磁盤中對應(yīng)的頁加載到該緩存頁的位置。每當(dāng)需要從磁盤中加載一個頁到 Buffer Pool 中時,就從 Free 鏈表中取一個空閑的緩存頁,并且把該緩存頁對應(yīng)的控制塊的信息填上,然后把該緩存頁對應(yīng)的 Free 鏈表節(jié)點(diǎn)從鏈表中移除,表示該緩存頁已經(jīng)被使用了,并且把該頁寫入 Lru 鏈表。

在初始化的時候,Buffer pool 中所有的頁都是空閑頁,需要讀數(shù)據(jù)時,就會從 Free 鏈表中申請頁,但是物理內(nèi)存不可能無限增大,數(shù)據(jù)庫的數(shù)據(jù)卻是在不停增大的,所以 Free 鏈表的頁是會用完的。

因此需要考慮把已經(jīng)緩存的頁從 Buffer pool 中刪除一部分,進(jìn)而需要考慮如何刪除及刪除哪些已經(jīng)緩存的頁。假設(shè)一共訪問了 n 次頁,那么被訪問的頁在緩存中的次數(shù)除以 n 就是緩存命中率,緩存命中率越高,和磁盤的 IO 交互也就越少 。

為了提高緩存命中率,InnoDB 在傳統(tǒng) Lru 算法的基礎(chǔ)上做了優(yōu)化,解決了兩個問題:1、預(yù)讀失效 2、緩存池污染

寫操作

Buffer pool 另一個主要的功能是「加速寫」,即當(dāng)需要修改一個頁面的時候,先將這個頁面在緩沖池中進(jìn)行修改,記下相關(guān)的重做日志,這個頁面的修改就算已經(jīng)完成了。

被修改的頁面真正刷新到磁盤,這個是后臺刷新線程來完成的。前面頁面更新是在緩存池中先進(jìn)行的,那它就和磁盤上的頁不一致了,這樣的緩存頁被稱為臟頁(dirty page)。

問題:這些被修改的頁面什么時候刷新到磁盤?以什么樣的順序刷新到磁盤?

最簡單的做法就是每發(fā)生一次修改就立即同步到磁盤上對應(yīng)的頁上,但是頻繁的往磁盤中寫數(shù)據(jù)會嚴(yán)重的影響程序的性能。所以每次修改緩存頁后,不能立即把修改同步到磁盤上,而是在未來的某個時間點(diǎn)進(jìn)行同步,由后臺刷新線程依次刷新到磁盤,實現(xiàn)修改落地到磁盤。

但是如果不立即同步到磁盤的話,那之后再同步的時候如何判斷 Buffer Pool 中哪些頁是臟頁,哪些頁從來沒被修改過呢?

InnoDB 并沒有一次性把所有的緩存頁都同步到磁盤上,InnoDB 創(chuàng)建一個存儲臟頁的鏈表,凡是在 Lru 鏈表中被修改過的頁都需要加入這個鏈表中,因為這個鏈表中的頁都是需要被刷新到磁盤上的,所以這個鏈表也叫 Flush 鏈表,鏈表的構(gòu)造和 Free 鏈表一致。

這里的臟頁修改指的此頁被加載進(jìn) Buffer Pool 后第一次被修改,只有第一次被修改時才需要加入 Flush 鏈表,對于已經(jīng)存在在 Flush 鏈表中的頁,如果這個頁被再次修改就不會再放到 Flush 鏈表。

需要注意,臟頁數(shù)據(jù)實際還在 Lru 鏈表中,而 Flush 鏈表中的臟頁記錄只是通過指針指向 Lru 鏈表中的臟頁。并且在 Flush 鏈表中的臟頁是根據(jù) oldest_lsn(這個值表示這個頁第一次被更改時的 lsn 號,對應(yīng)值 oldest_modification,每個頁頭部記錄)進(jìn)行排序刷新到磁盤的,值越小表示要最先被刷新,避免數(shù)據(jù)不一致。

免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺僅提供信息存儲服務(wù)。文章僅代表作者個人觀點(diǎn),不代表本平臺立場,如有問題,請聯(lián)系我們,謝謝!

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時聯(lián)系本站刪除。
換一批
延伸閱讀

LED驅(qū)動電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關(guān)鍵字: 驅(qū)動電源

在工業(yè)自動化蓬勃發(fā)展的當(dāng)下,工業(yè)電機(jī)作為核心動力設(shè)備,其驅(qū)動電源的性能直接關(guān)系到整個系統(tǒng)的穩(wěn)定性和可靠性。其中,反電動勢抑制與過流保護(hù)是驅(qū)動電源設(shè)計中至關(guān)重要的兩個環(huán)節(jié),集成化方案的設(shè)計成為提升電機(jī)驅(qū)動性能的關(guān)鍵。

關(guān)鍵字: 工業(yè)電機(jī) 驅(qū)動電源

LED 驅(qū)動電源作為 LED 照明系統(tǒng)的 “心臟”,其穩(wěn)定性直接決定了整個照明設(shè)備的使用壽命。然而,在實際應(yīng)用中,LED 驅(qū)動電源易損壞的問題卻十分常見,不僅增加了維護(hù)成本,還影響了用戶體驗。要解決這一問題,需從設(shè)計、生...

關(guān)鍵字: 驅(qū)動電源 照明系統(tǒng) 散熱

根據(jù)LED驅(qū)動電源的公式,電感內(nèi)電流波動大小和電感值成反比,輸出紋波和輸出電容值成反比。所以加大電感值和輸出電容值可以減小紋波。

關(guān)鍵字: LED 設(shè)計 驅(qū)動電源

電動汽車(EV)作為新能源汽車的重要代表,正逐漸成為全球汽車產(chǎn)業(yè)的重要發(fā)展方向。電動汽車的核心技術(shù)之一是電機(jī)驅(qū)動控制系統(tǒng),而絕緣柵雙極型晶體管(IGBT)作為電機(jī)驅(qū)動系統(tǒng)中的關(guān)鍵元件,其性能直接影響到電動汽車的動力性能和...

關(guān)鍵字: 電動汽車 新能源 驅(qū)動電源

在現(xiàn)代城市建設(shè)中,街道及停車場照明作為基礎(chǔ)設(shè)施的重要組成部分,其質(zhì)量和效率直接關(guān)系到城市的公共安全、居民生活質(zhì)量和能源利用效率。隨著科技的進(jìn)步,高亮度白光發(fā)光二極管(LED)因其獨(dú)特的優(yōu)勢逐漸取代傳統(tǒng)光源,成為大功率區(qū)域...

關(guān)鍵字: 發(fā)光二極管 驅(qū)動電源 LED

LED通用照明設(shè)計工程師會遇到許多挑戰(zhàn),如功率密度、功率因數(shù)校正(PFC)、空間受限和可靠性等。

關(guān)鍵字: LED 驅(qū)動電源 功率因數(shù)校正

在LED照明技術(shù)日益普及的今天,LED驅(qū)動電源的電磁干擾(EMI)問題成為了一個不可忽視的挑戰(zhàn)。電磁干擾不僅會影響LED燈具的正常工作,還可能對周圍電子設(shè)備造成不利影響,甚至引發(fā)系統(tǒng)故障。因此,采取有效的硬件措施來解決L...

關(guān)鍵字: LED照明技術(shù) 電磁干擾 驅(qū)動電源

開關(guān)電源具有效率高的特性,而且開關(guān)電源的變壓器體積比串聯(lián)穩(wěn)壓型電源的要小得多,電源電路比較整潔,整機(jī)重量也有所下降,所以,現(xiàn)在的LED驅(qū)動電源

關(guān)鍵字: LED 驅(qū)動電源 開關(guān)電源

LED驅(qū)動電源是把電源供應(yīng)轉(zhuǎn)換為特定的電壓電流以驅(qū)動LED發(fā)光的電壓轉(zhuǎn)換器,通常情況下:LED驅(qū)動電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關(guān)鍵字: LED 隧道燈 驅(qū)動電源
關(guān)閉