MySQL 5.7 動態修改 innodb_buffer_pool_size


MySQL5.7開始支持動態修改innodb_buffer_pool_size大小,每個 buffer_pool_instance都由同樣個數的chunk組成(chunks數組), 每個chunk內存大小為 innodb_buffer_pool_chunk_size(實際會偏大5%,用於存放chuck中的block信息)。buffer pool以 innodb_buffer_pool_chunk_size為單位進行動態增大和縮小。調整前后 innodb_buffer_pool_size應一直保持innodb_buffer_pool_chunk_size*innodb_buffer_pool_instances倍數

同樣的buffer pool動態調整大小由后台線程 buf_resize_thread,set命令會立即返回。通過 InnoDB_buffer_pool_resize_status可以查看調整的運行狀態。

resize流程:
1.如果開啟了AHI,需禁用AHI

2.如果是收縮內存

3.開始resize

4.如果禁用了AHI,此時開啟

$ 鎖住所有instance的buffer_pool,page_hash
$ 收縮pool:以chunk為單位釋放要收縮的內存
$ 清空withdraw列表buf_pool->withdraw
$ 增大pool:分配新的chunk
$ 重新分配buf_pool->chunks
$ 如果改變/縮小超過2倍,會重置page hash,改變桶大小
$ 釋放buffer_pool,page_hash鎖
$ 如果改變/縮小超過2倍,會重啟和buffer pool大小相關的內存結構,如鎖系統(lock_sys_resize),AHI(btr_search_sys_resize), 數據字段(dict_resize)等
$ 計算需收縮的chunk數, 從chunks開始尾部刪除指定個數的chunk.
$ 鎖buf_pool
$ 從free_list中摘除待刪chunk的page放入待刪鏈表buf_pool->withdraw
$ 如果待刪chunk的page為臟頁,則刷臟
$ 重新加載LRU中要刪除的頁,從LRU中摘除,重新從free列表獲取page老的page放入待刪鏈表buf_pool->withdraw
$ 釋放buffer pool鎖
$ 如果需收縮的chunk pages沒有收集全,重復2-6
   由上可以看出,擴大內存比縮小內存相對容易些。縮小內存時,如果遇到有事務一直未提交且占用了待收縮的page時,導致收縮一直重試,error log會打印這種重試信息, 包含可能引用此問題的事務信息。為了避免頻繁重試,每次重試的時間間隔會指數增長。

   以上步驟中resize階段buffer pool會不可用,此階段會鎖所有buffer pool, 但此階段都是內存操作,時間比較短。收縮內存階段耗時可能會很長,也有一定影響,但是每次都是以instance為單位進行鎖定的。 總的來說,buffer pool 動態調整大小對應用的影響並不大。

   重新加載LRU中要刪除的頁的影響

   search 過程中btr游標保存的page可能重新加載過,自適應哈希保存的root page也可能重新加載過, 都需要重新讀取。

   轉:https://blog.51cto.com/u_12592884/2697590


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM