Mysql數據庫InnoDB緩衝池(Buffer Pool)

1.InnoDB緩衝池簡介
InnoDB在內存中維護一個叫做緩衝池的存儲區域來緩存數據和索引。瞭解InnoDB緩衝區如何工作,如何利用它來在內存中保存被頻繁訪問的數據,對Mysql調優至關重要。可以對InnoDB緩衝的各方面進行配置來改善Mysql的性能。
1)理想來講,可以將緩衝池設置爲實際需要的值,爲服務器上運行的其他進程保留足夠內存以防發生過度也交換。緩衝池越大,InnoDB就越像一個內存庫,從磁盤上讀取一次數據,後續只從內存中讀取數據。
2)大內存64位系統,可以把緩衝池分爲多個部分,以便最小化併發操作時對內存結構的衝突。
3)儘管會突然增加類似備份或報表類的活動,但依然可以將頻繁訪問的數據保存在內存中。
4)預期不久將需要某些數據頁,則可以控制InnoDB將數據頁預先異步讀入緩衝池的時間和方式。
5)可以控制後臺進程何時將髒頁刷出到磁盤,以及InnoDB是否基於工作負載動態調整刷出髒頁的頻率。
6)可以對InnoDB緩衝池刷新各方面行爲進行微調一提高性能。
7)可以配置InnoDB保留當前的緩衝池狀態,以避免服務器重啓後發生過長的溫啓動時間。也可以在在服務器運行時保存當前的緩衝池狀態。


2.Innodb緩衝池LRU算法
Innodb將緩衝池作爲鏈表並通過最近最少使用(LRU)的變種算法進行管理。當需要爲緩衝池增加新頁時,InnoDB對最近最少使用的頁進行驅逐,並將新頁增加到鏈表的中部。這種“中間點插入策略”將鏈表看做兩個子鏈表:
1)鏈表頭部,爲最近被存取過的“新”(或“年輕”)頁的子鏈表。
2)鏈表尾部,爲最近較少被存取的“舊”頁的子鏈表。
這個算法把經常被查詢使用的頁保持在新的子鏈表中。舊的子鏈表則包含較少用到的頁;這些頁時將來被驅逐的候選頁。LRU算法默認操作如下:
1)緩衝池的3/8用作舊的子鏈表。
2)鏈表中點是新的子鏈表尾部與舊的子鏈表頭部銜接的邊界。
3)當InnoDB往緩衝池讀入一個頁時,會將該頁插入到鏈表的中點(舊的子鏈表的頭部)。當用戶類似查詢的某個特定操作需要數據頁或InnoDB進行預讀操作時,InnoDB會將其讀入緩衝池。
4)存取就的子鏈表中的頁會使其變的“年輕”,因爲會將其移向緩衝池的頭部(新的子鏈表的頭部)。如果因爲需要而將一個頁讀入緩衝池,則立即發生首次讀取並使其變得年輕。如果因爲預讀而將一個頁讀入緩衝池,
則並不立即發生首次存取(也許在該頁被驅逐前根本就不會被讀取)。
5)隨着數據庫操作的進行,緩衝池中未被存取的頁通過移向鏈表尾部而變老。其他也變新的同事,新舊子鏈表中的頁變老。隨着頁被插入鏈表中點,舊子鏈表中的頁也會變老。最終,長時間未被使用的頁會到達舊子鏈表尾部而被驅逐。
默認的,查詢讀取的頁會立即移到新子鏈表,這意味着它們將會更長時間留在緩衝池中。表掃描(像mysqldump操作或沒有where子句的select語句引導致的)能將大量數據帶入緩衝池,並驅逐同等數量的舊數據,即使新數據還從未用過。類似的,被後臺進程預讀加載的頁,接着僅被存取一次就移到新鏈表的頭部。這些情況會頻繁的將被用過的頁推到就子鏈表,從而將被驅逐。
InnoDB標準監視輸出在屬於緩衝池LRU算法的BUFFER POOL AND MEMORY部分包含幾個域。


3.InnoDB緩衝池配置選項
有幾個配置選項會影響InnoDB緩衝池的不通方面。
1)innodb_buffer_pool_size:確定緩衝池的大小。如果緩衝池很小且系統有足夠的內存,設置較大的緩衝池能通過減少查詢訪問InnoDB表需要的磁盤I/O來改善性能。innodb_buffer_pool_size爲動態選項,其允許對緩衝池大小進行配置而無需重啓服務器。
2)innodb_buffer_pool_chunk_size:定義InnoDB緩衝池改變大小時的塊(chunk)大小。
3)innodb_buffer_pool_instances:將緩衝池分爲用戶指定數目的獨立區,每個有自己的LRU鏈表和相關的數據結構,以減少併發內存讀寫期間的衝突。該選項僅當將innodb_buffer_pool_size設置爲1GB及更高值時纔會起作用。指定的緩衝池的總大小會被分到所有的緩衝池實例。爲了達到最好性能,指定innodb_buffer_pool_instances和innodb_buffer_pool_size選項的組合值,以便每個緩衝池實例至少達到1GB。
4)innodb_old_blocks_pct:爲用作舊子鏈表的緩衝池指定一個近似比例。可以指定的範圍爲5~95。默認值爲37(即,緩衝池的3/8)。
5)innodb_old_blocks_time:指定首次訪問後插入舊子鏈表的頁,至少在舊子鏈表停留多少毫秒才能被移入新子鏈表。如果該值爲0,舊子鏈表中的頁被首次訪問後立即被移到新子鏈表,無論存取發生時該頁在舊子鏈表中已停留多久。如果該值大於0,則首次訪問後頁必須停留在舊子鏈表中至少指定的毫秒數後,再次發生訪問時才能移出舊子鏈表。例如:指定該值爲1000將導致頁首次訪問後停留在舊子鏈表1秒,纔可以被移到新子鏈表。將innodb_old_blocks_time設置爲大於0的值將防止一次表掃描所用的頁塞滿新子鏈表。一次掃描讀進頁中的數據行被連續不斷的訪問,但以後不再被用。如果innodb_old_blocks_time設置爲大於
處理該頁所用時間的值,則該頁一直停留在“舊”子鏈表中,並很快老化到舊子鏈表尾部和被驅逐。通過這種方式,用於一次性掃描的頁並不會影響新子鏈表中頻繁使用的頁。innodb_old_blocks_time可以動態設置,因此,可以在執行表掃描和導出時臨時改變該選項的值。
SET GLOBAL innodb_old_blocks_time = 1000;
... 執行掃描表的查詢 ...
SET GLOBAL innodb_old_blocks_time = 0;
如果打算通過用一張表的數據填充緩衝池來進行“熱身”,則該策略並不適合。例如:基準測試經常在服務器啓動時執行一個表或索引掃描,因爲一段時間日常使用後,這些數據通常將在緩衝池內。這種情況下,讓innodb_old_blocks_time保持爲0,至少熱身階段完成前保持爲0。
6)innodb_read_ahead_threshold:控制InnoDB將頁預讀進緩衝池的線性預讀的靈敏度。
7)innodb_random_read_ahead:開啓將頁預讀進緩衝池的隨機預讀技術。隨機預讀是不管頁的讀取順序,基於已在緩衝池中的頁來判斷其他頁不久將被用到的一項技術。innodb_random_read_ahead默認爲禁用。
8)innodb_adaptive_flushing:確定是否基於工作負載動態調整緩衝池中髒頁的刷出率。動態調整頁刷出率爲了避免突然爆發的I/O活動。該選項默認爲開啓。
9)innodb_adaptive_flushing_lwm:表示啓用自適應刷出時重做日誌容量百分比的低水位線。
10)innodb_flush_neighbors:確定從緩衝池刷出頁時是否也刷出同一個範圍內的其他髒頁。
11)innodb_flushing_avg_loops:InnoDB保持先前計算的刷出狀態快照的迭代次數,用於控制針對負載變化自適應刷出的反應速度。
12)innodb_lru_scan_depth:影響緩衝池刷出操作的算法和試探法的一個參數。主要用於性能專家對I/O密集的負載進行調試。該參數指定,每個緩衝池實例,page_cleaner線程尋找刷出的髒頁時要對緩衝池LRU鏈表進行多深的掃描。
13)innodb_max_dirty_pages_pct:InnoDB盡力從緩衝中刷出數據以便髒頁的百分比不超過該值。指定一個0~99的整數值。默認值爲75。
14)innodb_max_dirty_pages_pct_lwm:開啓預刷出控制髒頁率時表示髒頁百分比的低水位線。默認值0徹底禁用預刷出行爲。
15)innodb_buffer_pool_filename:指定一個用於保存innodb_buffer_pool_dump_at_shutdown或innodb_buffer_pool_dump_now產生的表空間ID和頁ID列表的文件名。
16)innodb_buffer_pool_dump_at_shutdown:爲了縮短下次重啓時溫啓動過程的耗時,指定mysql服務器關閉時是否記錄緩衝池中緩衝的頁。
17)innodb_buffer_pool_load_at_startup:指定在mysql服務器啓動時通過加載較早時間緩衝的相同頁來自動進行緩衝池熱身。該選項典型與innodb_buffer_pool_dump_at_shutdown一起使用。
18)innodb_buffer_pool_dump_now:立即記錄緩衝池中緩衝的頁。
19)innodb_buffer_pool_load_now:通過加載一套數據頁來立刻進行緩衝池熱身,而非等待服務器重啓。用於基準測試期間將緩衝內存帶回一個已知狀態,或運行報表查詢或維護後將mysql服務器恢復成其通常的工作負載。該選項典型與innodb_buffer_pool_dump_now一起使用。
20)innodb_buffer_pool_dump_pct:指定每個緩衝池中讀出和導出的最近被使用頁的百分比。其值範圍爲1~100。
21)innodb_buffer_pool_load_abort:中斷innodb_buffer_pool_load_at_startup或innodb_buffer_pool_load_now觸發的緩衝池內容恢復進程。
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章