前段時間,公司領導反映服務瞬時查詢緩慢,壓力比較大,針對這點,進行了一些了解與分析
1. 為什么需要innodb buffer pool?
在MySQL5.5之前,廣泛使用的和默認的存儲引擎是MyISAM。MyISAM使用操作系統緩存來緩存數據。InnoDB需要innodb buffer pool中處理緩存。所以非常需要有足夠的InnoDB buffer pool空間。
2. MySQL InnoDB buffer pool 里包含什么?
-
數據緩存
InnoDB數據頁面 -
索引緩存
索引數據 -
緩沖數據
臟頁(在內存中修改尚未刷新(寫入)到磁盤的數據) -
內部結構
如自適應哈希索引,行鎖等。
3. 如何設置innodb_buffer_pool_size?
innodb_buffer_pool_size默認大小為128M。最大值取決於CPU的架構。在32-bit平台上,最大值為2**32 -1,在64-bit平台上最大值為2**64-1。當緩沖池大小大於1G時,將innodb_buffer_pool_instances設置大於1的值可以提高服務器的可擴展性。
大的緩沖池可以減小多次磁盤I/O訪問相同的表數據。在專用數據庫服務器上,可以將緩沖池大小設置為服務器物理內存的80%。
3.1 配置緩沖池大小時,請注意以下潛在問題
-
物理內存爭用可能導致操作系統頻繁的paging
-
InnoDB為緩沖區和control structures保留了額外的內存,因此總分配空間比指定的緩沖池大小大約大10%。
-
緩沖池的地址空間必須是連續的,這在帶有在特定地址加載的DLL的Windows系統上可能是一個問題。
-
初始化緩沖池的時間大致與其大小成比例。在具有大緩沖池的實例上,初始化時間可能很長。要減少初始化時間,可以在服務器關閉時保存緩沖池狀態,並在服務器啟動時將其還原。
innodb_buffer_pool_dump_pct:指定每個緩沖池最近使用的頁面讀取和轉儲的百分比。 范圍是1到100。默認值是25。例如,如果有4個緩沖池,每個緩沖池有100個page,並且innodb_buffer_pool_dump_pct設置為25,則dump每個緩沖池中最近使用的25個page。innodb_buffer_pool_dump_at_shutdown:默認啟用。指定在MySQL服務器關閉時是否記錄在InnoDB緩沖池中緩存的頁面,以便在下次重新啟動時縮短預熱過程。innodb_buffer_pool_load_at_startup:默認啟用。指定在MySQL服務器啟動時,InnoDB緩沖池通過加載之前保存的相同頁面自動預熱。 通常與innodb_buffer_pool_dump_at_shutdown結合使用。
增大或減小緩沖池大小時,將以chunk的形式執行操作。chunk大小由innodb_buffer_pool_chunk_size配置選項定義,默認值為128 MB。
緩沖池大小必須始終等於或者是innodb_buffer_pool_chunk_size * innodb_buffer_pool_instances的倍數。
如果將緩沖池大小更改為不等於或等於innodb_buffer_pool_chunk_size * innodb_buffer_pool_instances的倍數的值,
則緩沖池大小將自動調整為等於或者是innodb_buffer_pool_chunk_size * innodb_buffer_pool_instances的倍數的值。
innodb_buffer_pool_size可以動態設置,允許在不重新啟動服務器的情況下調整緩沖池的大小。 可以通過狀態變量Innodb_buffer_pool_resize_status報告在線調整緩沖池大小操作的狀態。
執行語句
show status like 'Innodb_buffer_pool_resize%';

3.2 配置示例
在以下示例中,innodb_buffer_pool_size設置為1G,innodb_buffer_pool_instances設置為1。innodb_buffer_pool_chunk_size默認值為128M。
1G是有效的innodb_buffer_pool_size值,因為1G是innodb_buffer_pool_instances = 1 * innodb_buffer_pool_chunk_size = 128M的倍數
執行語句
show variables like 'innodb_buffer_pool%';
innodb_buffer_pool_size=(1024*1024)/innodb_buffer_pool_chunk_size/innodb_buffer_pool_instances

3.3 在線調整InnoDB緩沖池大小
SET GLOBAL innodb_buffer_pool_size = 3221225472
3.4 監控在線緩沖池調整進度
SHOW STATUS WHERE Variable_name='InnoDB_buffer_pool_resize_status';
4. 配置的innodb_buffer_pool_size是否合適?
當前配置的innodb_buffer_pool_size是否合適,可以通過分析InnoDB緩沖池的性能來驗證。
可以使用以下公式計算InnoDB緩沖池性能:
Performance = innodb_buffer_pool_reads / innodb_buffer_pool_read_requests * 100
innodb_buffer_pool_reads:表示InnoDB緩沖池無法滿足的請求數。需要從磁盤中讀取。
innodb_buffer_pool_read_requests:表示從內存中讀取邏輯的請求數。
例如,在我的服務器上,檢查當前InnoDB緩沖池的性能
show status like 'innodb_buffer_pool_read%';

Innodb_buffer_pool_reads/Innodb_buffer_pool_read_requests*100 即 1700/940668*100=0.18072263540378
意味着InnoDB可以滿足緩沖池本身的大部分請求。從磁盤完成讀取的百分比非常小。因此無需增加innodb_buffer_pool_size值。
InnoDB buffer pool 命中率:
InnoDB buffer pool 命中率 = innodb_buffer_pool_read_requests / (innodb_buffer_pool_read_requests + innodb_buffer_pool_reads ) * 100
此值低於99%,則可以考慮增加innodb_buffer_pool_size。
5. InnoDB緩沖池狀態變量有哪些?
可以運行以下命令進行查看:
show global status like '%innodb_buffer_pool_pages%';

說明:
- Innodb_buffer_pool_pages_data
InnoDB緩沖池中包含數據的頁數。 該數字包括臟頁面和干凈頁面。 使用壓縮表時,報告的Innodb_buffer_pool_pages_data值可能大於Innodb_buffer_pool_pages_total。
-
Innodb_buffer_pool_pages_dirty
顯示在內存中修改但尚未寫入數據文件的InnoDB緩沖池數據頁的數量(臟頁刷新)。 -
Innodb_buffer_pool_pages_flushed
表示從InnoDB緩沖池中刷新臟頁的請求數。 -
Innodb_buffer_pool_pages_free
顯示InnoDB緩沖池中的空閑頁面 -
Innodb_buffer_pool_pages_misc
InnoDB緩沖池中的頁面數量很多,因為它們已被分配用於管理開銷,例如行鎖或自適應哈希索引。此值也可以計算為Innodb_buffer_pool_pages_total - Innodb_buffer_pool_pages_free - Innodb_buffer_pool_pages_data。 -
Innodb_buffer_pool_pages_total
InnoDB緩沖池的總大小,以page為單位。 -
innodb_buffer_pool_reads
表示InnoDB緩沖池無法滿足的請求數。需要從磁盤中讀取。 -
innodb_buffer_pool_read_requests
它表示從內存中邏輯讀取的請求數。 -
innodb_buffer_pool_wait_free
通常,對InnoDB緩沖池的寫入發生在后台。 當InnoDB需要讀取或創建頁面並且沒有可用的干凈頁面時,InnoDB首先刷新一些臟頁並等待該操作完成。 此計數器計算這些等待的實例。 如果已正確設置innodb_buffer_pool_size,則此值應該很小。如果大於0,則表示InnoDb緩沖池太小。 -
innodb_buffer_pool_write_request
表示對緩沖池執行的寫入次數。
以此檢查緩沖池,緩沖池配置合理可以適當優化
