MySQL將內存用在了哪裏
本片文章參考官網講述MySQL是如何分配內部內存,同時涉及到如何合適設的置內存分配以及如何監控內存的使用情況
官方文檔
MySQL在啟動時默認被分配給512MB RAM,可以通過設置相關內存參數對其進行設置,下面時MySQL使用內存的地方
1、InnoDB buffer pool 用於緩存表數據、索引及其他的一些輔助緩沖池,為了高效進行緩存管理,buffer pool 應用多種LRU(least recently used)算法,將相鄰的page串成鏈,管理冷熱數據
innodb_buffer_pool_size控制buffer pool的大小,MySQL5.7開始,可以在線變更配置
- 為了提高並行,可以將buffer pool分成多個實例,默認如果buffer pool的大小達到1GB,instance的個數時8,可以通過
innodb_buffer_pool_instances配置
2、所有的線程共享MyISAM key buffer ,受key_buffer_size參數控制
每打開一個MyISAM表,索引文件只會打開一次,當多個線程並行打開同一個表時,此表只會被打開一次,但是單個線程內,表結構、列結構及3*N(N是最長行的大小,不包括blob列)的緩存都會被分配內存。BLOB列需要5到8個bytes加上BLOB數據。MyISAM存儲引擎額外分配一個row buffer 用於內部
3、內部的內存臨時表如果超過設置大小則轉為磁盤表,控制內存臨時表的大小參數有tmp_table_size、
max_heap_table_size,on-disk臨時表的存儲引擎受
internal_tmp_disk_storage_engine設置
4、performance schema根據服務器的實際負載自增分配內存,已分配的內存只有在MySQL重啟時才會釋放
5、為每個客戶端線程分配線程所需的內存,包括
-
A stack (
thread_stack
) -
A connection buffer (
net_buffer_length
) -
A result buffer (
net_buffer_length
)
connection buffer 和result buffer 最初的大小是 net_buffer_length
bytes, 但是根據需要可以動態的擴大到 max_allowed_packet
bytes 。 result buffer 收縮到 net_buffer_length
max_digest_length
bytes
6、所有線程共享共同的基礎系統內存
7、當線程不再被使用時,為其分配的內存將被回收並重新歸為系統,除非使用長連接,線程回到緩沖池,對其分配的內存不會釋放
8、順序讀表被分配一個read buffer ,受read_buffer_size控制
9、隨機讀取行數據會被分配random-read buffer ,受read_rnd_buffer_size控制
10、所有連接都在一次執行中執行,大多數連接都可以在不使用臨時表的情況下完成。
11、大多數的排序會占用一個sort buffer和0到2個臨時文件(根據結果集的大小而定)
12、幾乎所有的解析和計算都是在線程本地和可重用的內存池中完成的。
13、對於每個含有BLOB列的表,會占用一個自動擴大的buffer用於讀入更大的BLOB值,如果進行全表掃描,這個buffer會擴大到和最大的BLOB值一樣大
14、MySQL的table cache需要內存和描述符,所有使用中的表結構的處理程序都緩存在table cache中,管理原則時先進先出(FIFO),table cache受table_open_cache控制
MySQL同樣需要內存緩存表結構文件,受table_definition_cache控制,不需要描述符,可以增大table definition cache來加快表的打開速度
15、flush tables 命令會關閉所有不使用的表並標記當前正在使用的表在調用他們的線程結束後被關閉。會有效的釋放內存,flush tables在表都關閉後才會返回
16、MySQL會緩存權限、server、插件相關的命令文本,只有執行flush privileges後才會釋放內存
監控MySQL的使用情況
查看innodb相關的內存監控是否開啟,默認不開啟
mysql> SELECT * FROM performance_schema.setup_instruments WHERE NAME LIKE ‘%memory/innodb%‘; +-------------------------------------------+---------+-------+ | NAME | ENABLED | TIMED | +-------------------------------------------+---------+-------+ | memory/innodb/adaptive hash index | NO | NO | | memory/innodb/buf_buf_pool | NO | NO | | memory/innodb/dict_stats_bg_recalc_pool_t | NO | NO | | memory/innodb/dict_stats_index_map_t | NO | NO | | memory/innodb/dict_stats_n_diff_on_level | NO | NO | | memory/innodb/other | NO | NO | | memory/innodb/row_log_buf | NO | NO | | memory/innodb/row_merge_sort | NO | NO | | memory/innodb/std | NO | NO | | memory/innodb/trx_sys_t::rw_trx_ids | NO | NO | ...
設置開啟所有的memory instruments ,配置文件條件如下並重啟
performance-schema-instrument=‘memory/%=COUNTED‘
查看監控數據
mysql> SELECT * FROM performance_schema.memory_summary_global_by_event_name WHERE EVENT_NAME LIKE ‘memory/innodb/buf_buf_pool‘\G EVENT_NAME: memory/innodb/buf_buf_pool COUNT_ALLOC: 1 COUNT_FREE: 0 SUM_NUMBER_OF_BYTES_ALLOC: 137428992 SUM_NUMBER_OF_BYTES_FREE: 0 LOW_COUNT_USED: 0 CURRENT_COUNT_USED: 1 HIGH_COUNT_USED: 1 LOW_NUMBER_OF_BYTES_USED: 0 CURRENT_NUMBER_OF_BYTES_USED: 137428992 HIGH_NUMBER_OF_BYTES_USED: 137428992
通過sys庫查看當前server分配的所有內存
mysql> SELECT * FROM sys.memory_global_by_current_bytes WHERE event_name LIKE ‘memory/innodb/buf_buf_pool‘\G *************************** 1. row *************************** event_name: memory/innodb/buf_buf_pool current_count: 1 current_alloc: 131.06 MiB current_avg_alloc: 131.06 MiB high_count: 1 high_alloc: 131.06 MiB high_avg_alloc: 131.06 MiB # 細化查詢每個code area 分配的內存 mysql> SELECT SUBSTRING_INDEX(event_name,‘/‘,2) AS code_area, sys.format_bytes(SUM(current_alloc)) AS current_alloc FROM sys.x$memory_global_by_current_bytes GROUP BY SUBSTRING_INDEX(event_name,‘/‘,2) ORDER BY SUM(current_alloc) DESC; +---------------------------+---------------+ | code_area | current_alloc | +---------------------------+---------------+ | memory/innodb | 843.24 MiB | | memory/performance_schema | 81.29 MiB | | memory/mysys | 8.20 MiB | | memory/sql | 2.47 MiB | | memory/memory | 174.01 KiB | | memory/myisam | 46.53 KiB | | memory/blackhole | 512 bytes | | memory/federated | 512 bytes | | memory/csv | 512 bytes | | memory/vio | 496 bytes | +---------------------------+---------------+
MySQL將內存用在了哪裏