快速預熱innodb buffer pool

2021-07-03 06:52:09 字數 3567 閱讀 9824

早期,peter在實際的工作中總結了一些預熱buffer pool的sql語句,也就是通過人為模擬一些請求,盡可能地將我們所需的資料塊和索引載入到記憶體中。

1. 載入主鍵索引

select count(*) from tbl where no_index_col=0;

2. 載入非主鍵索引

select count(*) from tbl where index_col like 「%0%」;

3. 載入blob/text列

select count(*) from tbl where blob_col like 「%0%」;

4. 分段載入大表資料

select count(*) from tbl where id between 1 and 10000000 and no_index_col=0;

還有人使用blackhole引擎來進行預熱操作,通過替換不同的索引字段進行排序查詢,將所需資料載入。

create table temp_blackhole like tbl;

alter table temp_blackhole engine=blackhole;

select * from tbl order by id into temp_blackhole;

現在,percona已經完全在xtradb中實現這個功能,最初採用share memory buffer pool,目前採用dump/restore of the buffer pool。

1. share memory buffer pool

該方法在記憶體個劃出乙個共享段用於儲存buffer pool,使得這塊空間在mysqld啟動關閉前後都能備份訪問,不會因為mysqld關閉而將buffer pool的內容清除。但是,共享記憶體的使用必須遵守嚴格的要求:innodb引擎前後保持一致;innodb的page頁大小前後保持一致;innodb_buffer_pool_size的大小前後保持一致。否則,會遇到問題,這時就不能在使用共享空間,需要手動將其刪除。

innodb_buffer_pool_shm_key — 用於是否開啟共享記憶體的使用,0開啟,1不開啟。

innodb_buffer_pool_shm_checksum — 檢查共享空間中儲存的buffer pool是否有損壞。

/proc/sys/kernel/shmmax — 記憶體共享空間的大小可以通過系統下的該檔案去調整。

2. dump/restore of the buffer pool

從名字就可以知道這個預熱方法,先將buffer pool的內容dump出來,在資料目錄下會生成乙個ib_lru_dump的檔案,然後需要是再通過這個dump檔案將其恢復回去,這也正是我們最初的乙個想法。下面簡單說下它的實現過程,先需要了解下innodb buffer pool。

innodb buffer pool是記憶體中的一段儲存空間,由大小為16kb的page頁組成,是乙個列表頁,該列表按照lru的順序進行排列,所以也被叫作lru列表。buffer pool被分成兩個子列,前半段被稱為』young』,也就是經常被訪問到的塊,而後半段成為』old』,訪問次數較少的塊。當有新的塊被載入進來的時候,會被插入到兩端之間的位置,之後會隨著被訪問的頻繁程度,是保持遷移還是不斷後退,最後被替換出去。

在了解了innodb buffer pool之後,讓我麼來看看dump操作。我們知道磁碟的查詢更多是無序的隨機的操作,而載入到記憶體中的page會被重新組織成有序的排列。xtra_lru_dump的操作並不是簡單的將innodb_buffer_pool中的所有內容備份到ib_lru_dump檔案中,這樣會隨著innodb_buffer _pool_size的大小而變得很大,進而備份恢復時間也會變得不很樂觀,那麼怎麼做呢?事實上,只需備份page在buffer pool中的標誌資訊即可,即(space_id,page_no)這樣乙個列表,space_id表示page在buffer pool中lru的排列順序,page_no表示page在磁碟上的儲存位置。恢復時,按照page_no去磁碟中找到對應的page,而這個可以按照page_no的順序去查詢,可以近似看作是順序i/o,盡量避免隨機i/o的消耗,然後將查詢到的page按照space_id存到最初在lru列表中的位置,最後實現恢復到關閉服務之前的狀態。這個方法提供了自動和手動兩種實現操作。

自動引數設定:

innodb_buffer_pool_restore_at_startup/innodb_auto_lru_dump — 該引數可以控制是否開啟自動dump/restore的操作,只能通過手動完成;當為0時,表示不開啟自動操作,當為非0時,表示按照指定的時間週期dump操作,重啟後自動完成restore的操作。

p.s.: 該特性的選項innodb_auto_lru_dump是在xtradb的5.5.10-12.1版本中被引入,到5.5.10-20.1起將其重名為innodb_buffer_pool_restore_at_startup。

手動操作如下:

mysql> show status like 『innodb_buffer_pool_pages_data』;    — 檢視重啟前後當前page頁的個數

mysql> select * from information_schema.xtardb_admin_command /*!xtra_lru_dump*/;   — 備份innodb_buffer_pool

mysql> select * from information_schema.xtardb_admin_command /*!xtra_lru_restore*/;   — 恢復innodb_buffer_pool

p.s.: 以上手動備份恢復的操作語句還沒有加入到xtradb的任何版本中,只是在percona的test環境中實現了。

- takeaways -

innodb buffer pool是innodb效能提公升的核心,它既可以快取資料還可以快取索引。快取的資料部分是資料塊構成的page頁,而不像query cache僅存的sql對應的結果集。buffer pool上可以完成資料的更新變化,減少隨機i/o的操作,提高寫入效能,而query cache最忌諱表的資料更新,會導致相應的cache失效,帶來額外系統消耗。之前聽過這麼一句很精闢的對於buffer與cache的總結:buffer是用來加速寫,cache是用來緩衝讀。在實際中,盡可能的增大innodb_buffer_pool_size的大小,把頻繁訪問的資料都放到記憶體中來,盡可能減少innodb對於磁碟i/o的訪問,把innodb最大話成為乙個記憶體型引擎。

innodb_buffer_pool_size的大小,當系統啟動後,會比之前指定的要多出大小的10%,避免過大導致os發生swap動作,留出足夠的給os使用;show engine innodb status\g命令輸出中buffer pool and memory部分有關於buffer pool使用情況的提示,可以關注這麼三項:free buffers表示未被使用的,經過一段時間後,仍然保持不少的空閒buffer,說明該引數設定過大,如果為0,說明該引數設定的大小不能滿足需求;database pages表示目前有多少資料頁已經被快取到buffer pool中;flush list表示dirty pages的數量,有多少跟新的頁沒有被刷回磁碟,當快取的列表太大時,會使正常關閉mysqld變得很慢,也會使意外發生後crash recovery的動作只持續相當長時間(會是你無法忍受的);buffer pool hit rate表示buffer pool的使用效率。

快速預熱Buffer Pool緩衝池

在之前的版本裡,如果一台高負荷的機器重啟後,記憶體中大量的熱資料被清空,此時就會重新從磁碟載入到buffer pool緩衝池裡,這樣當高峰期間,效能就會變得很差,連線數就會很高。在mysql5.6裡,乙個新特性避免的這種問題的出現。你只需在my.cnf裡,加入如下 innodb buffer poo...

mysql 資料預熱 mysql預熱緩衝池

在資料庫壓力很大的情況下,重啟完資料庫,通過手工執行下列語句,把熱資料載入到innodb buffer pool緩衝池中進行預熱,從而避免早高峰連線數公升高,程式報錯。select count from user select count from 在mysql5.6裡為了解決上述問題,提供了乙個新...

快取預熱指令碼

快取預熱 在記憶體快取雪崩之後,如果沒有做持久化的話,會導致記憶體的所有資料丟失,導致mysql伺服器壓力過大,導致宕機,為了解決這個問題,需要準備乙個 預熱指令碼 header content type text html charset utf 8 mysql obj new mysqli 12...