<b>提要</b>
相對于納秒級的記憶體通路延時,普通的機械盤達到了毫秒級的随機通路延時,對于oltp應用來說,實體io絕對是目前資料庫管理系統的最大性能殺手,是以增加記憶體的大小,提高io的命中率無疑可以作為一種降低延遲時間的常用優化手段。
針對使用innodb引擎的mysql執行個體來說,增加buffer pool的大小,盡可能的提高buffer pool的命中率,減少實體io的機率,能極大的提升系統的吞吐量。
但是,随着記憶體越來越大,面臨着一個很嚴重的問題:當記憶體突然失效,或者執行個體異常crash後,面對相同的請求壓力,或者突然的大壓力,系統由于記憶體未命中會耗盡io資源,并導緻request響應變慢,形成雪崩效應。
<b>warmup特性</b>
mysql 5.6 innodb提供了warmup的功能,并增加了三個控制參數:
<dl></dl>
<dd>innodb_buffer_pool_dump_at_shutdown</dd>
<dd>innodb_buffer_pool_filename</dd>
<dd>innodb_buffer_pool_load_at_startup</dd>
<b>工作原理</b>
innodb啟動一個背景線程,等待一個條件變量:
1. 當系統shutdown的時候,如果innodb_buffer_pool_dump_at_shutdown=on,系統會notify condition,從buffer pool的lru連結清單中,讀取spaceid+page_no到innodb_buffer_pool_file檔案中,然後正常關閉。
2. 當系統startup的時候,如果innodb_buffer_pool_load_at_startup=on,并且存在innodb_buffer_pool_file,會讀取元資訊,進行異步io讀取資料加載到buffer pool中。
3. 為了防止系統運作過久,innodb_buffer_pool_file過時,無法反映目前熱點資料的情況,innodb又提供了一個innodb_buffer_pool_dump_now參數,set後會即時進行一次dump,覆寫掉老的檔案。
<b>那麼問題來了</b>
1. warmup是否影響startup的速度:
<dl><dd>不影響.啟動的時候,讀取innodb_buffer_pool_file, 排序後,進行異步io,不影響startup的速度。但現實的情況是:如果你是在業務高峰期出現crash,其實對于系統來說,先warmup後,再開放提供服務,更合适。</dd></dl>
2. 異常crash的時候,使用過時的中繼資料:
<dl><dd>如果異常crash,那麼就存在過時的innodb_buffer_pool_file,如果想避免這種情況,系統可以每隔一段時間,進行一次dump。</dd></dl>
3. dump是否導緻系統抖動
<dl><dd>dump的過程,會持有mutex,掃描lru連結清單,讀取中繼資料,如果在系統業務高峰期,可能會産生抖動。</dd></dl>
<b>改進</b>
mysql 5.7 又增強了warmup功能的使用:
1. 新增參數innodb_buffer_pool_dump_pct
<dl><dd>目前innodb的buffer pool可能設定的比較大,可以通過設定dump的比例,控制dump的速度和load時的量。</dd></dl>
2. innodb_io_capacity
<dd>控制load過程中,防止過量使用io資源,如果單機多執行個體的情況下,同時啟動執行個體,會使io過載。</dd>