innodb buffer pool有幾個目的:
-
緩存數據--眾所周知,這個占了buffer pool的大半空間
-
緩存目錄--數據字典
-
insert buffer
-
排序的內部結構--比如自適應hash的結構或者一些行鎖
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;
得到的結果:
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;
結果:
+----------+ | count(*) | +----------+ | 262142 | +----------+
聰明的同學自己算下使用的buffer pool是多大吧。
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;
結果:
+-------------------+--------------+ | 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的大部分空間。也可以看出來這里有幾種重要的頁類型:
-
INDEX: B-Tree index
-
IBUF_INDEX: Insert 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/