理解innodb buffer pool

innodb buffer pool有幾個目的:html

  • 緩存數據--衆所周知,這個佔了buffer pool的大半空間mysql

  • 緩存目錄--數據字典sql

  • insert buffer緩存

  • 排序的內部結構--好比自適應hash的結構或者一些行鎖url

1.查看錶的數據和索引使用狀況?

複製代碼

SELECT engine,  count(*) as TABLES,
  concat(round(sum(table_rows)/1000000,2),'M') rows,
  concat(round(sum(data_length)/(1024*1024*1024),2),'G') DATA,
  concat(round(sum(index_length)/(1024*1024*1024),2),'G') idx,
  concat(round(sum(data_length+index_length)/(1024*1024*1024),2),'G') total_size,  
  round(sum(index_length)/sum(data_length),2) idxfrac 
FROM information_schema.TABLES 
WHERE table_schema not in ('mysql', 'performance_schema', 'information_schema','test') 
GROUP BY engine ORDER BY sum(data_length+index_length) DESC LIMIT 10;

複製代碼

獲得的結果:spa

1
2
3
4
5
6
7
8
9
10
11
12
13
+--------+--------+----------+---------+--------+------------+---------+
| engine | TABLES | rows     | DATA    | idx    | total_size | idxfrac |
+--------+--------+----------+---------+--------+------------+---------+
| InnoDB |  71608 | 1644.51M | 130.79G | 82.76G | 213.55G    |    0.63 |
+--------+--------+----------+---------+--------+------------+---------+
 
idxfrac這個值越低越好,舉個例子,表裏只有一個惟一索引的數據以下:
+--------+--------+----------+---------+--------+------------+---------+
| engine | TABLES | rows     | DATA    | idx    | total_size | idxfrac |
+--------+--------+----------+---------+--------+------------+---------+
| InnoDB |     16 | 3120.61M | 386.59G | 58.09G | 444.68G    |    0.15 |
+--------+--------+----------+---------+--------+------------+---------+
可見idxfrac可見這個值越低越好。

2.獲取buffer pool佔的page個數:

select count(*) from information_schema.innodb_buffer_page;

結果:.net

+----------+
| count(*) |
+----------+
| 262142   |
+----------+

聰明的同窗本身算下使用的buffer pool是多大吧。rest

3.獲取page類型:

select page_type as Page_Type,sum(data_size)/1024/1024 as Size_in_MB 
from information_schema.innodb_buffer_page 
group by page_type 
order by Size_in_MB desc;

結果:code

複製代碼

+-------------------+--------------+
| Page_Type         | Size_in_MB   |
+-------------------+--------------+
| INDEX             | 158.66378689 |
| UNKNOWN           | 0.00000000   |
| TRX_SYSTEM        | 0.00000000   |
| SYSTEM            | 0.00000000   |
| FILE_SPACE_HEADER | 0.00000000   |
| IBUF_BITMAP       | 0.00000000   |
| EXTENT_DESCRIPTOR | 0.00000000   |
| ALLOCATED         | 0.00000000   |
| INODE             | 0.00000000   |
| BLOB              | 0.00000000   |
| UNDO_LOG          | 0.00000000   |
| IBUF_FREE_LIST    | 0.00000000   |
| IBUF_INDEX        | 0.00000000   |
+-------------------+--------------+

複製代碼

從這裏能夠看到數據和索引佔了buffer pool的大部分空間。也能夠看出來這裏有幾種重要的頁類型:orm

  • INDEX: B-Tree index

  • IBUF_INDEXInsert buffer index

  • UNKNOWN: not allocated / unknown state

  • TRX_SYSTEM: transaction system data

眼亮的同窗可能會問,你上面不是說會緩存數據嗎?怎麼這裏出來只有INDEX類型佔多半buffer pool?數據哪裏去了?數據在INDEX裏!!!數據在聚簇索引的葉子節點上。

4.buffer pool裏每一個索引的使用

select table_name as Table_Name, index_name as Index_Name,count(*) as Page_Count, sum(data_size)/1024/1024 as Size_in_MB 
from information_schema.innodb_buffer_page 
group by table_name, index_name 
order by Size_in_MB desc;

結果:

複製代碼

+--------------------------------------------+-----------------+------------+-------------+
| Table_Name                                 | Index_Name      | Page_Count | Size_in_MB  |
+--------------------------------------------+-----------------+------------+-------------+
| `magento`.`core_url_rewrite`               | PRIMARY         |       2829 | 40.64266014 |
| `magento`.`core_url_rewrite`               | FK_CORE_URL_... |        680 |  6.67517281 |
| `magento`.`catalog_product_entity_varchar` | PRIMARY         |        449 |  6.41064930 |
| `magento`.`catalog_product_index_price`    | PRIMARY         |        440 |  6.29357910 |
| `magento`.`catalog_product_entity`         | PRIMARY         |        435 |  6.23898315 |
+--------------------------------------------+-----------------+------------+-------------+

複製代碼

5.一個典型的buffer pool使用監控:

從這裏圖裏咱們能夠看到buffer pool幾乎是被填滿的,另外預留了10%的空間用來作其餘用途。

6.通常怎麼設置buffer pool大小呢?

warm rows data size + warm indexes size (excl. clustered) + 20%

7.如何預熱buffer pool?

在InnoDB上面執行select語句:

  • 對於聚簇索引來講,大多數狀況經過SELECT COUNT(*) 加載到buffer pool中了。

  • 對於二級索引來講,要執行一些簡單的語句來抓取所有數據,好比select * from tbname where 索引的第一列。或者select * from tbname force index(二級索引) where colname <>0.

另外,MySQL5.7支持動態修改buffer pool:

mysql> SET GLOBAL innodb_buffer_pool_size=size_in_bytes;

8.Dump & restore

在MySQL (5.6+), Percona Server (5.5.10+) or MariaDB (10.0+)能夠經過如下配置把buffer pool裏面的數據dump出來,並在啓動的時候加載到內存中:

  • innodb_buffer_pool_dump_at_shutdown=ON

  • innodb_buffer_pool_load_at_startup=ON

參考資料:

https://michael.bouvy.net/blog/en/2015/01/18/understanding-mysql-innodb-buffer-pool-size/ 

http://www.speedemy.com/mysql/17-key-mysql-config-file-settings/innodb_buffer_pool_size/ 

相關文章
相關標籤/搜索