mysql innodb缓存策略之Buffer Pool
The InnoDB Buffer Pool
? ?Innodb 持有一個(gè)存儲(chǔ)區(qū)域叫做buffer pool是為了在內(nèi)存中緩存數(shù)據(jù)和索引,知道innodb bufferpool怎么工作,和利用它讀取頻繁訪問(wèn)的數(shù)據(jù),是mysql優(yōu)化重要的方面。
? ?理想狀況下,把bufferpool的大小調(diào)整到足夠大,留下足夠的內(nèi)存空間給其他該服務(wù)器上的進(jìn)程(使其無(wú)缺頁(yè)即可)。bufferpool越大,innodb 月表現(xiàn)為內(nèi)存型數(shù)據(jù)庫(kù),從硬盤(pán)上一次讀取數(shù)據(jù),之后并成了從內(nèi)存中讀取數(shù)據(jù)。buffer pool甚至緩存那些因?yàn)閕nsert,update操作而改變的數(shù)據(jù)(insert buffer),所以隨機(jī)磁盤(pán)寫(xiě)可以聚集在一塊得到更好的性能。
? ?innodb 把緩存池作為鏈?zhǔn)焦芾?#xff0c;利用LRU(least recently used)算法,當(dāng)添加新block到pool中時(shí)(無(wú)空間),innodb 替換(驅(qū)逐)一個(gè)最近最少使用的block,然后把新的block添加到鏈表的中間,"midpoint insertion strategy"策略把鏈表看出兩條子鏈。
? ? ?1:在鏈表的頭部,是由一些“NEW”(or "young")block 組成的最近剛被訪問(wèn)的子鏈;
? ? ?2:在鏈表的尾部,是由一些'old' block組成的最近沒(méi)被訪問(wèn)(或者最少被訪問(wèn)的)的子鏈;
?
?該算法使大量查詢(xún) blocks 保持在 ?new sublist.?old sublist 持有最少使用的 blocks;這些blocks將成為替換或驅(qū)逐的候選者。
? ? ?1:3/8 的buffer pool 的大小分配給old sublist
? ? ?2: 鏈表的 midpoint (中間插入點(diǎn)) 是new sublist 尾部和 old sublist頭部聚合的地方
? ? ?3:當(dāng) innodb 讀取一個(gè)block進(jìn) buffer pool時(shí),插入到midpoint(old sublist 的頭部),block被讀取發(fā)生在 客戶(hù)端操作,eg: sql查詢(xún),或者innodb特性 readahead(預(yù)讀);
? ? ?4:當(dāng)訪問(wèn)在old sublist中一個(gè) block時(shí),使其變成'young',把它移動(dòng)到 buffer pool的頭部(new sublist的頭部),如果該block 被讀取是因?yàn)榭蛻?hù)端sql查詢(xún),則第一次訪問(wèn)立即發(fā)生,并且該block變成'young'。如果該block被讀取是因?yàn)閞ead ahead,第一次唄訪問(wèn)不會(huì)發(fā)生,并且有可能在該Block被替換之前根本不能發(fā)生);
? ? ?5:隨著數(shù)據(jù)庫(kù)操作,在buffer pool 中的沒(méi)被訪問(wèn)的blocks(年紀(jì)大的)被移動(dòng)到鏈表的尾部.在old sublist中的blocks 比插入在midpoint上的block老,最終,一個(gè)Block一段長(zhǎng)時(shí)間未被使用會(huì)到達(dá)old sublist的尾部會(huì)被替換。
? ? ?默認(rèn)情況下,被讀取的blocks會(huì)立即移動(dòng)到 NEW sublist 的 head,同時(shí)意味著他們待著buffer pool中很長(zhǎng)一段時(shí)間。當(dāng)掃表時(shí)(eg, mysqldump 操作,或者 沒(méi)有where語(yǔ)句的select操作 )可以使大量的blocks ?push into buffer pool中,并且驅(qū)逐大量的older 數(shù)據(jù),即使那些所謂剛加入的 new blocks 不會(huì)再次被訪問(wèn),相同的,read ahead 后臺(tái)線程一次載入大量的blocks ?,這些情況使經(jīng)常被訪問(wèn)的blocks push into 到 old sublist中,然后它們成為被驅(qū)逐的候選者。
??一些innodb 系統(tǒng)變量控制著buffer pool的大小和使你調(diào)整LRU算法
? ? 1:innodb buffer pool size
? ? ? ?指明Buffer pool的大小,如果你的buffer pool 空間小,并且有充足的空間,使pool大點(diǎn)可以減小磁盤(pán)IO的次數(shù)來(lái)提高性能;
/* 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的大小默認(rèn)是128MB,分為8個(gè)instance,每個(gè)instance是16KB,并且對(duì)數(shù)據(jù)的操作是按頁(yè)進(jìn)行讀寫(xiě)的,一頁(yè)就是16KB。
? ??buffer_pool是一個(gè)list,目的是為了使用LRU cache機(jī)制;減少并發(fā)寫(xiě)操作時(shí)鎖的粒度。
2: innodb buffer pool instances : 分成多個(gè)獨(dú)立的區(qū)域,各個(gè)區(qū)域相同,來(lái)減少在并發(fā)內(nèi)存讀寫(xiě)操作的競(jìng)爭(zhēng);
? ? 3:innodb old blocks pct:默認(rèn)3/8;
? ? 4: ?innodb old blocks time:?指定多長(zhǎng)時(shí)間以毫秒為單位(ms),block插入到老子列表必須呆在那里第一次訪問(wèn)后多久,才能搬到新的子列表(解決預(yù)讀時(shí),緩存污染問(wèn)題);
總結(jié)
以上是生活随笔為你收集整理的mysql innodb缓存策略之Buffer Pool的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: AE动画导出json工具:bodymov
- 下一篇: A star算法优化二