對於使用InnoDB儲存引擎的表來說,是以頁為單位來管理儲存空間的,作為記憶體和磁碟之間換入換出的基本粒度。當我們將某頁從磁碟載入到記憶體中,就會進行磁碟I/O。而磁碟I/O的開銷非常影響整體效能,如果我們直接從記憶體中讀取對應的頁,那豈不是減少了磁碟I/O帶來的效能損耗,效率會提升很多。基於此,緩衝池(
Buffer Pool
) 出現了,那麼接下來,我們就來談談InnoDB中的Buffer Pool。
緩衝池(Buffer Pool)
有人會想,既然緩衝池這麼好,那我們將所有資料都儲存到緩衝池中不就好了,不不不,緩衝池是作業系統分配的一片連續的記憶體。而記憶體相比於磁碟的容量小得多,並且價格昂貴。那麼作業系統會給緩衝池分配多少記憶體呢?
- 預設情況下,緩衝池的大小為128MB;
#當然,如果你的機器的記憶體容量非常大,可以在設定檔中設定啟動選項參數innodb_buffer_pool_size
單位是位元組,最小不能小於5MB。
緩衝池的內部結構
緩衝池將作業系統分配的這一連續的內存,劃分成若干個大小預設為16KB的頁(緩衝頁)【此時還沒有真正的磁碟頁被快取到Buffer Pool中】,當我們從磁碟換入一個頁到緩衝池中,如何分配位置呢?因此就需要一些控制資訊來標識這些緩衝池中的緩衝頁,這些控制資訊都存放在一個叫做控制塊的記憶體區域中,與緩衝頁一一對應。控制塊的大小也是固定的。因此在這片連續的記憶體空間中,難免會產生記憶體碎片。綜上,緩衝池的內部結構如下:
- 緩衝頁
- 控制區塊:頁號、緩衝頁在緩衝池中的位址、鍊錶節點資訊等。
- 記憶體碎片【若記憶體分配得當,記憶體碎片可有可無】
緩衝池的管理
上面在控制塊中提到了鍊錶節點訊息,那麼鍊錶節點是用來做什麼的呢?是為了更好的管理緩衝池中的頁。而鍊錶就是用來連結控制塊的,因為控制塊與緩衝頁是一一對應的。
1)空閒鍊錶
將所有空閒的緩衝頁對應的控制區塊連結起來,形成的鍊錶。
解決的問題:從磁碟換入一個頁到緩衝池中,如何區分緩衝池中的哪個頁是空閒的呢?而有了空閒鍊錶之後,換入一個磁碟頁到緩衝池中時,就直接從空閒鍊錶中取得一個空閒的緩衝頁,並將磁碟頁中對應的資訊填到緩衝頁對應的控制塊中,然後將該控制塊從空閒鍊錶中刪除即可。
2)更新鍊錶
若修改了緩衝池中的緩衝頁的數據,導致其與磁碟中資料不一致,該頁稱為髒頁。將所有髒頁對應的控制區塊連結起來形成更新鍊錶,在將來的某個時間根據該鍊錶將對應快取頁的資料刷新到磁碟中。
3)LRU鍊錶
緩衝池的大小是有限的,如果快取的頁超出了緩衝池的大小,即沒有空閒的緩衝頁了,當有新的頁要添加到緩衝池時,採取LRU的策略將舊的緩衝頁從緩衝池中移除,然後將新的頁加入進來。由於LRU鍊錶涉及的內容較多,我們接下來單獨介紹。
LRU鍊錶所蘊含的「哲理」
先提一下預讀機制
在I/O上的最佳化機制,預讀顧名思義,會異步地把某有些頁面載入到緩衝池中,預計很快就會需要這些頁面,這些請求在一個範圍內引入所有頁面,就是所謂的局部性原理
,目的是減少磁碟I/O。
在了解預讀機制之前,先回顧InnoDB邏輯儲存單元:表空間(tablespace)→段(segment )→區(extent)→頁(page)。其中特意提一下區,後面會用到:一個區就是物理位置上連續的64頁
,也就是一個區的大小是1MB.
- Linear read-ahead(線性預讀):一種基於依序存取的緩衝池中的頁面來預測可能很快需要哪些頁面的技術。透過設定參數innodb_read_ahead_threshold,若順序存取的某個區的頁面超過這個參數的值,會觸發非同步讀取請求來讀取下一個區中全部的頁面到緩衝池中。
- Random read-ahead(隨機預讀):可以根據緩衝池中已經存在的頁面預測何時可能需要頁面,而不管這些頁面的讀取順序如何。如果在緩衝池中發現同一個區段的13個連續頁面,InnoDB會非同步發出一個請求來預取該區段的剩餘頁面。透過配置變數innodb_random_read_ahead來控制隨機讀取的。
傳統LRU對緩衝頁是如何管理的呢?
利用LRU演算法對最近最少使用的緩衝頁進行管理,形成對應的鍊錶,方便用於淘汰。
當訪問一個頁【即最近訪問】
- 該頁在緩衝池中,將對應控制塊移至LRU鍊錶頭部
- 該頁不在緩衝池中,淘汰尾部最近最少使用的頁,從磁碟中加載進來該頁並放在LRU鍊錶頭部
那麼為什麼InnoDB不使用這麼直觀的LRU演算法呢?原因如下:
-
預讀失效
預先閱讀緩衝池中的頁都會放到LRU鍊錶的頭部,但其中很多頁可能並不會被讀取。
-
緩衝池污染
很多使用頻率較低的頁載入到緩衝池中,會把使用頻率較高的頁從緩衝池中淘汰掉。例如全表掃描
優化後的LRU對緩衝頁是如何管理的呢?
基於上述缺點,優化後的具體方法將傳統LRU鍊錶劃分為兩部分:熱資料區域【年輕區】&冷資料區域【老年區】
- 熱資料區【年輕區】:使用頻率高的緩衝區頁
- 冷資料區【老年區】:使用頻率低的區域
#結構簡圖如下所示:
如圖所示,熱資料區域與冷資料區域分別佔用不同比例,那麼我們可以透過innodb_old_blocks_pct
啟動選項來控制冷資料區域所佔比例。
改進後的LRU如何更好的解決預讀失敗問題呢?
- 某頁在初次載入到緩衝池時,先淘汰掉冷資料區域尾部的控制區塊(即其對應的頁淘汰掉),然後新頁對應的控制區塊會先放到冷資料區域的頭部。
- 若後續該頁不被進行存取就會慢慢從冷資料區域中被淘汰掉,整體不會影響熱資料區域存取頻繁的緩衝頁。
改進後的LRU如何更好的解決緩衝池污染問題呢?
先說結論,並沒有很好的最佳化這個問題,原因如下【以全表掃描為例】:
- 某個初次造訪的頁同樣會放到冷資料區域的頭部,但後續訪問又會將其放到熱資料區域的頭部,這樣同樣會把存取頻率較高的頁給擠掉。
那麼到底該如何解決緩衝池污染問題呢?
- 緩衝池引入了冷資料區域時間視窗機制,即只有後續存取該頁與第一存取該頁的時間間隔大於規定的視窗值,就會將該頁從冷資料區域移到熱數據區域的頭部。小於規定的視窗值,就不會進行移動操作。
- 同樣,視窗值可透過
innodb_old_blocks_time
參數【單位ms】來設置,預設1000ms,而1s會篩選掉大部分像全表掃描這樣的操作。例如在一次全表掃描過程中,多次造訪一個頁面的時間間隔不會超過1s。
緩衝池VS查詢快取
緩衝池和查詢快取是一個東西嗎? →不是
- 緩衝池會盡量將經常使用的資料保存起來,在MySQL進行頁面讀取操作的時候,首先會判斷該頁面是否在緩衝池中,如果存在就直接讀取,如果不存在,就會透過記憶體或磁碟將頁面存放到緩衝池中再進行讀取。
- 查詢快取是提前把查詢結果快取起來,這樣下次就不需要執行就可以直接拿到結果。需要說明的是,在MySQL中的查詢緩存,不是緩存查詢計劃,而是查詢對應的結果。命中條件苛刻,而且只要資料表發生變化,查詢快取就會失效,因此命中率低。
【相關推薦:mysql影片教學】
以上是帶你了解MySQL中的資料庫緩衝池(Buffer Pool)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本篇文章给大家带来了关于mysql的相关知识,其中主要介绍了关于架构原理的相关内容,MySQL Server架构自顶向下大致可以分网络连接层、服务层、存储引擎层和系统文件层,下面一起来看一下,希望对大家有帮助。

在mysql中,可以利用char()和REPLACE()函数来替换换行符;REPLACE()函数可以用新字符串替换列中的换行符,而换行符可使用“char(13)”来表示,语法为“replace(字段名,char(13),'新字符串') ”。

mysql的msi与zip版本的区别:1、zip包含的安装程序是一种主动安装,而msi包含的是被installer所用的安装文件以提交请求的方式安装;2、zip是一种数据压缩和文档存储的文件格式,msi是微软格式的安装包。

方法:1、利用right函数,语法为“update 表名 set 指定字段 = right(指定字段, length(指定字段)-1)...”;2、利用substring函数,语法为“select substring(指定字段,2)..”。

转换方法:1、利用cast函数,语法“select * from 表名 order by cast(字段名 as SIGNED)”;2、利用“select * from 表名 order by CONVERT(字段名,SIGNED)”语句。

本篇文章给大家带来了关于mysql的相关知识,其中主要介绍了关于MySQL复制技术的相关问题,包括了异步复制、半同步复制等等内容,下面一起来看一下,希望对大家有帮助。

本篇文章给大家带来了关于mysql的相关知识,其中主要介绍了mysql高级篇的一些问题,包括了索引是什么、索引底层实现等等问题,下面一起来看一下,希望对大家有帮助。

在mysql中,可以利用REGEXP运算符判断数据是否是数字类型,语法为“String REGEXP '[^0-9.]'”;该运算符是正则表达式的缩写,若数据字符中含有数字时,返回的结果是true,反之返回的结果是false。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

PhpStorm Mac 版本
最新(2018.2.1 )專業的PHP整合開發工具

Dreamweaver Mac版
視覺化網頁開發工具

SecLists
SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。

DVWA
Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中

MinGW - Minimalist GNU for Windows
這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。