mysql innodb缓存策略之Buffer Pool
The InnoDB Buffer Pool
? ?Innodb 持有一個存儲區域叫做buffer pool是為了在內存中緩存數據和索引,知道innodb bufferpool怎么工作,和利用它讀取頻繁訪問的數據,是mysql優化重要的方面。
? ?理想狀況下,把bufferpool的大小調整到足夠大,留下足夠的內存空間給其他該服務器上的進程(使其無缺頁即可)。bufferpool越大,innodb 月表現為內存型數據庫,從硬盤上一次讀取數據,之后并成了從內存中讀取數據。buffer pool甚至緩存那些因為insert,update操作而改變的數據(insert buffer),所以隨機磁盤寫可以聚集在一塊得到更好的性能。
? ?innodb 把緩存池作為鏈式管理,利用LRU(least recently used)算法,當添加新block到pool中時(無空間),innodb 替換(驅逐)一個最近最少使用的block,然后把新的block添加到鏈表的中間,"midpoint insertion strategy"策略把鏈表看出兩條子鏈。
? ? ?1:在鏈表的頭部,是由一些“NEW”(or "young")block 組成的最近剛被訪問的子鏈;
? ? ?2:在鏈表的尾部,是由一些'old' block組成的最近沒被訪問(或者最少被訪問的)的子鏈;
?
?該算法使大量查詢 blocks 保持在 ?new sublist.?old sublist 持有最少使用的 blocks;這些blocks將成為替換或驅逐的候選者。
? ? ?1:3/8 的buffer pool 的大小分配給old sublist
? ? ?2: 鏈表的 midpoint (中間插入點) 是new sublist 尾部和 old sublist頭部聚合的地方
? ? ?3:當 innodb 讀取一個block進 buffer pool時,插入到midpoint(old sublist 的頭部),block被讀取發生在 客戶端操作,eg: sql查詢,或者innodb特性 readahead(預讀);
? ? ?4:當訪問在old sublist中一個 block時,使其變成'young',把它移動到 buffer pool的頭部(new sublist的頭部),如果該block 被讀取是因為客戶端sql查詢,則第一次訪問立即發生,并且該block變成'young'。如果該block被讀取是因為read ahead,第一次唄訪問不會發生,并且有可能在該Block被替換之前根本不能發生);
? ? ?5:隨著數據庫操作,在buffer pool 中的沒被訪問的blocks(年紀大的)被移動到鏈表的尾部.在old sublist中的blocks 比插入在midpoint上的block老,最終,一個Block一段長時間未被使用會到達old sublist的尾部會被替換。
? ? ?默認情況下,被讀取的blocks會立即移動到 NEW sublist 的 head,同時意味著他們待著buffer pool中很長一段時間。當掃表時(eg, mysqldump 操作,或者 沒有where語句的select操作 )可以使大量的blocks ?push into buffer pool中,并且驅逐大量的older 數據,即使那些所謂剛加入的 new blocks 不會再次被訪問,相同的,read ahead 后臺線程一次載入大量的blocks ?,這些情況使經常被訪問的blocks push into 到 old sublist中,然后它們成為被驅逐的候選者。
??一些innodb 系統變量控制著buffer pool的大小和使你調整LRU算法
? ? 1:innodb buffer pool size
? ? ? ?指明Buffer pool的大小,如果你的buffer pool 空間小,并且有充足的空間,使pool大點可以減小磁盤IO的次數來提高性能;
/* If the default value of innodb_buffer_pool_size is increased to be more than BUF_POOL_SIZE_THRESHOLD (srv/srv0start.cc), then srv_buf_pool_instances_default can be removed and 8 used instead. The problem with the current setup is that with 128MiB default buffer pool size and 8 instances by default we would emit a warning when no options are specified. */ // 128MiB / 8 = 16KB static MYSQL_SYSVAR_LONGLONG(buffer_pool_size, srv_buf_pool_curr_size,PLUGIN_VAR_RQCMDARG |PLUGIN_VAR_PERSIST_AS_READ_ONLY,"The size of the memory buffer InnoDB uses to ""cache data and indexes of its tables.",NULL, innodb_buffer_pool_size_update,static_cast<longlong>(srv_buf_pool_def_size),static_cast<longlong>(srv_buf_pool_min_size),longlong{srv_buf_pool_max_size}, 1024 * 1024L);innodb_buffer_pool_size的大小默認是128MB,分為8個instance,每個instance是16KB,并且對數據的操作是按頁進行讀寫的,一頁就是16KB。
? ??buffer_pool是一個list,目的是為了使用LRU cache機制;減少并發寫操作時鎖的粒度。
2: innodb buffer pool instances : 分成多個獨立的區域,各個區域相同,來減少在并發內存讀寫操作的競爭;
? ? 3:innodb old blocks pct:默認3/8;
? ? 4: ?innodb old blocks time:?指定多長時間以毫秒為單位(ms),block插入到老子列表必須呆在那里第一次訪問后多久,才能搬到新的子列表(解決預讀時,緩存污染問題);
總結
以上是生活随笔為你收集整理的mysql innodb缓存策略之Buffer Pool的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: AE动画导出json工具:bodymov
- 下一篇: MySQL字符串拼接、分组拼接字符串