date:20140530
auth:Jinhtml
參考:
http://dev.mysql.com/doc/refman/5.5/en/server-status-variables.html#
http://dev.mysql.com/doc/refman/5.5/en/memory-use.html
http://blog.csdn.net/wyzxg/article/details/7268122
http://blog.csdn.net/wyzxg/article/details/7268175mysql
*.線程獨享內存
*.全局共享內存
全局共享內存相似ORACLE的系統全局區SGA,線程獨享內存相似ORACLE的進程全局區PGA算法
1、線程獨享內存sql
在MySQL中,線程獨享內存主要用於各客戶端鏈接線程存儲各類操做的獨享數據,如線程棧信息,分組排序操做,數據讀寫緩衝,結果集暫存等等,並且大多數能夠經過相關參數來控制內存的使用量。數據庫
* 線程棧信息使用內存(thread_stack):
主要用來存放每個線程自身的標識信息,如線程id,線程運行時基本信息等等,咱們能夠經過 thread_stack 參數來設置爲每個線程棧分配多大的內存。
Global,No Dynamic,Default 192K(32bit), 256K(32bit),
推薦配置:默認緩存
* 排序使用內存(sort_buffer_size):
MySQL 用此內存區域進行排序操做(filesort),完成客戶端的排序請求。當咱們設置的排序區緩存大小沒法知足排序實際所需內存的時候,MySQL會將數據寫入磁盤文件來完成排序。因爲磁盤和內存的讀寫性能徹底不在一個數量級,
因此sort_buffer_size參數對排序操做的性能影響絕對不可小視。排序操做的實現原理請參考:MySQL Order By的實現分析。
何時會用到?
對結果集排序時
使用確認:
能夠經過查詢計劃中的Extra列的值爲Using file-sort來證明使用了和這個緩衝區。
>explain select * from user1;
Global Session,Dynamic,Default 2M(32bit), 2M(32bit),
推薦配置:8M(內存足夠的狀況下),默認(內存緊張的狀況)
優化建議:一種說法是增大能夠提升order by,group by性能,防止數據寫入磁盤佔用IO資源,還有一種說法是不推薦增長這個緩衝區的大小,理由是當值太大時可能會下降查詢的執行速度。目前我沒有實驗證明。服務器
* Join操做使用內存(join_buffer_size):
應用程序常常會出現一些兩表(或多表)Join的操做需求,MySQL在完成某些Join需求的時候(all/index join),爲了減小參與Join的「被驅動表」的讀取次數以提升性能,須要使用到Join Buffer來協助完成Join操做
(具體Join實現算法請參考:MySQL中的 Join 基本實現原理)。當Join Buffer過小,MySQL 不會將該Buffer存入磁盤文件,而是先將Join Buffer中的結果集與須要Join的表進行Join操做,而後清空Join Buffer中的數據,
繼續將剩餘的結果集寫入此Buffer中,如此往復。這勢必會形成被驅動表須要被屢次讀取,成倍增長IO訪問,下降效率。
何時會用到?
當查詢必須鏈接兩個表(或多個)的數據集而且不能使用索引時,這個緩衝區會被用到。這個緩衝區專門爲每一個線程的無索引連接操做準備的。
使用確認:
能夠經過查詢計劃中的Extra列的值爲Using join bufer來證明使用了和這個緩衝區。
>explain select * from user1;
+------+-------------+-------+-------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-------+-------+---------------+------+---------+------+------+-------------+
| 1 | SIMPLE | user1 | index | NULL | name | 78 | NULL | 3 | Using index |
+------+-------------+-------+-------+---------------+------+---------+------+------+-------------+
Global Session,Dynamic,Default 128K 各版本平臺最大值不同
推薦配置:8M(內存足夠的狀況下),默認(內存緊張的狀況)
優化建議:有一種說法是增長這個緩衝區的大小不會加快全鏈接操做的速度。目前我沒有實驗證明。網絡
* 順序讀取數據緩衝區使用內存(read_buffer_size):
這部份內存主要用於當須要順序讀取數據的時候,如沒法使用索引的狀況下的全表掃描,全索引掃描等。在這種時候,MySQL按照數據的存儲順序依次讀取數據塊,每次讀取的數據快首先會暫存在read_buffer_size中,
當buffer空間被寫滿或者所有數據讀取結束後,再將buffer中的數據返回給上層調用者,以提升效率。
Global Session,Dynamic,Default 128K
推薦配置:4M/8Msession
* 隨機讀取數據緩衝區使用內存(read_rnd_buffer_size):
和順序讀取相反,當MySQL進行非順序讀取(隨機讀取)數據塊的時候,會利用這個緩衝區暫存讀取的數據。如根據索引信息讀取表數據,根據排序後的結果集與表進行Join等等。
總的來講,就是當數據塊的讀取須要知足必定的順序的狀況下,MySQL就須要產生隨機讀取,進而使用到read_rnd_buffer_size 參數所設置的內存緩衝區。
Global Session,Dynamic,Default 256K
推薦配置:8M數據結構
* 鏈接信息及返回客戶端前結果集暫存使用內存(net_buffer_lenth):
這部分用來存放客戶端鏈接線程的鏈接信息和返回客戶端的結果集。當MySQL開始產生能夠返回的結果集,會在經過網絡返回給客戶端請求線程以前,會先暫存在經過net_buffer_lenth所設置的緩衝區中,
等知足必定大小的時候纔開始向客戶端發送,以提升網絡傳輸效率。不過net_buffer_lenth參數所設置的僅僅只是該緩存區的初始化大小,MySQL會根據實際須要自行申請更多的內存以知足需求,
但最大不會超過 max_allowed_packet 參數大小。
Global Session,Dynamic,Default 16K
推薦配置:默認 16K
* 批量插入暫存使用內存(bulk_insert_buffer_size):
當咱們使用如 insert … values(…),(…),(…)… 的方式進行批量插入的時候,MySQL會先將提交的數據放如一個緩存空間中,當該緩存空間被寫滿或者提交完全部數據以後,MySQL纔會一次性將該緩存空間中的數據寫入數據庫並清空緩存。
此外,當咱們進行 LOAD DATA INFILE操做來將文本文件中的數據Load進數據庫的時候,一樣會使用到此緩衝區。
Global Session,Dynamic,Default 8M
推薦配置:默認 8M
* 臨時表使用內存(tmp_table_size):
當咱們進行一些特殊操做如須要使用臨時表才能完成的Order By,Group By 等等,MySQL可能須要使用到臨時表。當咱們的臨時表較小(小於tmp_table_size 參數所設置的大小)的時候,MySQL會將臨時表建立成內存臨時表,
只有當tmp_table_size所設置的大小沒法裝下整個臨時表的時候,MySQL纔會將該表建立成MyISAM存儲引擎的表存放在磁盤上。不過,當另外一個系統參數 max_heap_table_size 的大小還小於 tmp_table_size 的時候,
MySQL將使用 max_heap_table_size 參數所設置大小做爲最大的內存臨時表大小,而忽略tmp_table_size 所設置的值。並且 tmp_table_size 參數從 MySQL 5.1.2 纔開始有,以前一直使用 max_heap_table_size。
誰小誰生效.另外還有一個參數max_tmp_tables,沒有使用
tmp_table_size
Global Session,Dynamic,Default 16M
推薦配置:64M
max_heap_table_size
Global Session,Dynamic,Default 8M
This variable sets the maximum size to which user-created MEMORY tables are permitted to grow
這個變量定義了MEMORY存儲引擎表的最大容量。
This variable is also used in conjunction with tmp_table_size to limit the size of internal in-memory tables. See
這個變量也與tmp_table_size一塊兒使用限制內部內存表的大小。請見
http://dev.mysql.com/doc/refman/5.5/en/internal-temporary-tables.html
推薦配置:64M
主要根據業務以及服務器內存來調整,若是有須要到則能夠調整到。GB竟然使用2G的配置,汗
目前沒有一個簡便的方式來肯定內部臨時表的總容量。能夠經過MySQL狀態變量created_tmp_tables和created_tmp_disk_tables來肯定建立了臨時表和基於磁盤的臨時表
mysql> show global status like 'create%tables';
+-------------------------+-------+
| Variable_name | Value |
+-------------------------+-------+
| Created_tmp_disk_tables | 0 |
| Created_tmp_tables | 0 |
+-------------------------+-------+
5.5中,可使用PERFORMANCE—SCHEMA來幫助統計基於磁盤的臨時表的總大小
補充說明:上面所列舉的MySQL線程獨享內存僅僅只是全部線程獨享內存中的部分,並非所有,只是這些可能對MySQL的性能產生較大的影響,且能夠經過系統參數進行調節。
因爲以上內存都是線程獨享,極端狀況下的內存整體使用量將是全部鏈接線程的總倍數。因此在設置過程當中必定要謹慎,切不可爲了提高性能就盲目的增大各參數值,
避免由於內存不夠而產生Out Of Memory異常或者是嚴重的Swap交換反而下降總體性能。
2、全局共享內存
全局共享內則主要是MySQL Instance以及底層存儲引擎用來暫存各類全局運算及可共享的暫存信息,如
存儲查詢緩存的 Query Cache,
緩存鏈接線程的 Thread Cache,
緩存表文件句柄信息的 Table Cache,
緩存二進制日誌的 BinLog Buffer,
緩存MyISAM存儲引擎索引鍵的 Key Buffer
存儲InnoDB數據和索引的 InnoDB Buffer Pool
等等。下面針對 MySQL 主要的共享內存進行一個簡單的分析。
* MyISAM索引緩存 Key Buffer(key_buffer_size):
MyISAM 索引緩存將MyISAM表的索引信息(.MYI文件)緩存在內存中,以提升其訪問性能。這個緩存能夠說是影響MyISAM存儲引擎性能的最重要因素之一了,經過 key_buffere_size 設置可使用的最大內存空間。
注意:即便運行一個所有采用innodb的模式,仍須要定義一個索引碼緩衝區,由於MYSQL元信息與MyISAM定義相同。
Global ,Dynamic,Default 8M
推薦配置:默認 8M
如何確認key_buffer_size不夠用?
使用show full proceslist的State列中,值Repairing the keycache是一個明顯的指標,它指出當前索引碼緩衝區大小不足以執行當前運行的SQL語句。這將致使額外的磁盤I/O開銷。
* 查詢緩存 Query Cache (query_cache_size):
http://dev.mysql.com/doc/refman/5.5/en/query-cache-configuration.html
http://dev.mysql.com/doc/refman/5.5/en/query-cache-status-and-maintenance.html
查詢緩存是MySQL比較獨特的一個緩存區域,用來緩存特定Query的結果集(Result Set)信息,且共享給全部客戶端。經過對Query語句進行特定的Hash計算以後與結果集對應存放在Query Cache中,以提升徹底相同的Query語句的相應速度。
當咱們打開MySQL的Query Cache以後,MySQL接收到每個SELECT類型的Query以後都會首先經過固定的Hash算法獲得該Query的Hash值,而後到Query Cache中查找是否有對應的Query Cache。若是有,則直接將Cache的結果集返回給客戶端。
若是沒有,再進行後續操做,獲得對應的結果集以後將該結果集緩存到Query Cache中,再返回給客戶端。當任何一個表的數據發生任何變化以後,與該表相關的全部Query Cache所有會失效,因此Query Cache對變動比較頻繁的表並非很是適用,
但對那些變動較少的表是很是合適的,能夠極大程度的提升查詢效率,如那些靜態資源表,配置表等等。爲了儘量高效的利用Query Cache,MySQL針對Query Cache設計了多個query_cache_type值
和兩個Query Hint:SQL_CACHE和SQL_NO_CACHE。當query_cache_type設置爲0(或者 OFF)的時候不使用Query Cache,當設置爲1(或者 ON)的時候,當且僅當Query中使用了SQL_NO_CACHE 的時候MySQL會忽略Query Cache,
當query_cache_type設置爲2(或者DEMAND)的時候,當且僅當Query中使用了SQL_CACHE提示以後,MySQL纔會針對該Query使用Query Cache。能夠經過query_cache_size來設置可使用的最大內存空間。
Global Dynamic,Default 0
推薦配置:16M
如何肯定系統query cache的狀況?
show global status like 'Qcache%';或者
select * from information_schema.GLOBAL_STATUS where VARIABLE_NAME like 'Qcache%';
公式:
(Qcache_hits/Qcache_hits+Com_select+1)*100來肯定查詢緩存的有效性
mysql> show variables like 'query_cache_size';
+------------------+----------+
| Variable_name | Value |
+------------------+----------+
| query_cache_size | 16777216 |
+------------------+----------+
1 row in set (0.00 sec)
mysql> show global status like 'Qcache%';
+-------------------------+------------+
| Variable_name | Value |
+-------------------------+------------+
| Qcache_free_blocks | 535 |
| Qcache_free_memory | 4885448 |
| Qcache_hits | 1858574835 |
| Qcache_inserts | 1619931831 |
| Qcache_lowmem_prunes | 802889469 |
| Qcache_not_cached | 825000679 |
| Qcache_queries_in_cache | 4411 |
| Qcache_total_blocks | 9554 |
+-------------------------+------------+
8 rows in set (0.00 sec)
mysql> show global status like 'Com_select';
+---------------+------------+
| Variable_name | Value |
+---------------+------------+
| Com_select | 2445037535 |
+---------------+------------+
1 row in set (0.00 sec)
* 鏈接線程緩存 Thread Cache(thread_cache_size):
鏈接線程是MySQL爲了提升建立鏈接線程的效率,將部分空閒的鏈接線程保持在一個緩存區以備新進鏈接請求的時候使用,這尤爲對那些使用短鏈接的應用程序來講能夠極大的提升建立鏈接的效率。
當咱們經過thread_cache_size設置了鏈接線程緩存池能夠緩存的鏈接線程的大小以後,能夠經過(Connections - Threads_created) / Connections * 100% 計算出鏈接線程緩存的命中率。
注意,這裏設置的是能夠緩存的鏈接線程的數目,而不是內存空間的大小。
Global,Dynamic,Default 0
推薦配置:8個
如何肯定系統Thread Cache的狀況?
mysql> show global status like 'Threads_created';
+-----------------+-------+
| Variable_name | Value |
+-----------------+-------+
| Threads_created | 506 |
+-----------------+-------+
1 row in set (0.00 sec)
mysql> show global status like 'connections';
+---------------+----------+
| Variable_name | Value |
+---------------+----------+
| Connections | 16513711 |
+---------------+----------+
1 row in set (0.00 sec)
16513711-506/16513711 * 100% =99.9938% 很高的命中率啊 這臺之只讀的slave
* 表緩存 Table Cache(table_open_cache):
表緩存區主要用來緩存表文件的文件句柄信息,在 MySQL5.1.3以前的版本經過table_cache參數設置,但從MySQL5.1.3開始改成table_open_cache來設置其大小。當咱們的客戶端程序提交Query給MySQL的時候,
MySQL須要對Query所涉及到的每個表都取得一個表文件句柄信息,若是沒有Table Cache,那麼MySQL就不得不頻繁的進行打開關閉文件操做,無疑會對系統性能產生必定的影響,Table Cache 正是爲了解決這一問題而產生的。
在有了Table Cache以後,MySQL每次須要獲取某個表文件的句柄信息的時候,首先會到Table Cache中查找是否存在空閒狀態的表文件句柄。若是有,則取出直接使用,沒有的話就只能進行打開文件操做得到文件句柄信息。
在使用完以後,MySQL會將該文件句柄信息再放回Table Cache 池中,以供其餘線程使用。注意,這裏設置的是能夠緩存的表文件句柄信息的數目,而不是內存空間的大小。
Global,Dynamic,Default 400
推薦配置:根據內存配置4G 2048 大於最大Opened_tables
如何肯定系統table_open_cache的狀況?
mysql> show variables like 'table_open_cache';
+------------------+-------+
| Variable_name | Value |
+------------------+-------+
| table_open_cache | 512 |
+------------------+-------+
1 row in set (0.00 sec)
mysql> show global status like 'open%_tables';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Open_tables | 512 |
| Opened_tables | 6841 |
+---------------+-------+
2 rows in set (0.00 sec)
調優參考:
http://blog.zfcms.com/article/282
http://www.kuqin.com/database/20120815/328904.html
兩個參數的值。其中Open_tables是當前正在打開表的數量,Opened_tables是全部已經打開表的數量。
若是Open_tables的值已經接近table_cache的值,且Opened_tables還在不斷變大,則說明mysql正在將緩存的表釋放以容納新的表,此時可能須要加大table_cache的值。對於大多數狀況,比較適合的值:
Open_tables / Opened_tables >= 0.85
Open_tables / table_cache <= 0.95
若是對此參數的把握不是很準,VPS管理百科給出一個很保守的設置建議:把MySQL數據庫放在生產環境中試運行一段時間,而後把參數的值調整得比Opened_tables的數值大一些,而且保證在比較高負載的極端條件下依然比Opened_tables略大。
在mysql默認安裝狀況下,table_cache的值在2G內存如下的機器中的值默認時256到 512,若是機器有4G內存,則默認這個值是2048,
* 表定義信息緩存 Table definition Cache (table_definition_cache):
表定義信息緩存是從 MySQL5.1.3 版本纔開始引入的一個新的緩存區,用來存放表定義信息。當咱們的 MySQL 中使用了較多的表的時候,此緩存無疑會提升對錶定義信息的訪問效率。
MySQL 提供了 table_definition_cache 參數給咱們設置能夠緩存的表的數量。注意,這裏設置的是能夠緩存的表定義信息的數目,而不是內存空間的大小。
The number of table definitions (from .frm files) that can be stored in the definition cache. If you use a large number of tables, you can create a large table definition cache to speed up opening of tables.
Global, Dynamic, Default 400
推薦配置:根據內存配置4G 2048 和Table Cache同樣便可
* 二進制日誌緩衝區Binlog Cache( binlog_cache_size):
二進制日誌緩衝區主要用來緩存因爲各類數據變動操作所產生的 Binary Log 信息。爲了提升系統的性能,MySQL 並非每次都是將二進制日誌直接寫入 Log File,而是先將信息寫入 Binlog Buffer 中,
當知足某些特定的條件(如 sync_binlog參數設置)以後再一次寫入 Log File 中。咱們能夠經過 binlog_cache_size 來設置其可使用的內存大小,同時經過 max_binlog_cache_size 限制其最大大小
(當單個事務過大的時候 MySQL 會申請更多的內存)。當所需內存大於 max_binlog_cache_size 參數設置的時候,MySQL 會報錯:「Multi-statement transaction required more than ‘max_binlog_cache_size’ bytes of storage」。
Global,Dynamic,Default 32K
推薦配置:2M
* InnoDB 日誌緩衝區 InnoDB Log Buffer (innodb_log_buffer_size):
這是 InnoDB 存儲引擎的事務日誌所使用的緩衝區。相似於 Binlog Buffer,InnoDB 在寫事務日誌的時候,爲了提升性能,也是先將信息寫入 Innofb Log Buffer 中,當知足 innodb_flush_log_trx_commit 參數所設置的相應條件(或者日誌緩衝區寫滿)以後,纔會將日誌寫到文件(或者同步到磁盤)中。能夠經過 innodb_log_buffer_size 參數設置其可使用的最大內存空間。
注:innodb_flush_log_trx_commit 參數對 InnoDB Log 的寫入性能有很是關鍵的影響。該參數能夠設置爲0,1,2,解釋以下:
0:log buffer中的數據將以每秒一次的頻率寫入到log file中,且同時會進行文件系統到磁盤的同步操做,可是每一個事務的commit並不會觸發任何log buffer 到log file的刷新或者文件系統到磁盤的刷新操做;
1:在每次事務提交的時候將log buffer 中的數據都會寫入到log file,同時也會觸發文件系統到磁盤的同步;
2:事務提交會觸發log buffer 到log file的刷新,但並不會觸發磁盤文件系統到磁盤的同步。此外,每秒會有一次文件系統到磁盤同步操做。
此外,MySQL文檔中還提到,這幾種設置中的每秒同步一次的機制,可能並不會徹底確保很是準確的每秒就必定會發生同步,還取決於進程調度的問題。實際上,InnoDB 可否真正知足此參數所設置值表明的意義正常 Recovery 仍是受到了不一樣 OS 下文件系統以及磁盤自己的限制,可能有些時候在並無真正完成磁盤同步的狀況下也會告訴 mysqld 已經完成了磁盤同步。
Global,Dynamic,Default 8M
推薦配置:8M 默認
* InnoDB 數據和索引緩存 InnoDB Buffer Pool(innodb_buffer_pool_size):
InnoDB Buffer Pool 對 InnoDB 存儲引擎的做用相似於 Key Buffer Cache 對 MyISAM 存儲引擎的影響,主要的不一樣在於 InnoDB Buffer Pool 不只僅緩存索引數據,還會緩存表的數據,
並且徹底按照數據文件中的數據快結構信息來緩存,這一點和 Oracle SGA 中的 database buffer cache 很是相似。因此,InnoDB Buffer Pool 對 InnoDB 存儲引擎的性能影響之大就可想而知了。
能夠經過 (Innodb_buffer_pool_read_requests - Innodb_buffer_pool_reads) / Innodb_buffer_pool_read_requests * 100% 計算獲得 InnoDB Buffer Pool 的命中率。
global級別,不可動態變動 Default 128M
設置InnoDB數據和索引內存緩存空間大小
配置方式:配置文件中配置
選擇參數:50 - 80 % RAM
mysql> show variables like '%innodb_buffer%';
+------------------------------+-----------+
| Variable_name | Value |
+------------------------------+-----------+
| innodb_buffer_pool_instances | 1 |
| innodb_buffer_pool_size | 268435456 |
+------------------------------+-----------+
2 rows in set (0.00 sec)
經過show global status和show engine innodb status\G的BUFFER POOL AND MEMORY
mysql> show global status like '%innodb_buffer%';
+---------------------------------------+--------------+
| Variable_name | Value |
+---------------------------------------+--------------+
| Innodb_buffer_pool_pages_data | 15684 |
| Innodb_buffer_pool_bytes_data | 256966656 |
| Innodb_buffer_pool_pages_dirty | 210 |
| Innodb_buffer_pool_bytes_dirty | 3440640 |
| Innodb_buffer_pool_pages_flushed | 372378403 |
| Innodb_buffer_pool_pages_free | 1 |
| Innodb_buffer_pool_pages_misc | 698 |
| Innodb_buffer_pool_pages_total | 16383 |
| Innodb_buffer_pool_read_ahead_rnd | 0 |
| Innodb_buffer_pool_read_ahead | 691803 |
| Innodb_buffer_pool_read_ahead_evicted | 41350 |
| Innodb_buffer_pool_read_requests | 170965099291 |
| Innodb_buffer_pool_reads | 5392513 |
| Innodb_buffer_pool_wait_free | 0 |
| Innodb_buffer_pool_write_requests | 5825388207 |
+---------------------------------------+--------------+
15 rows in set (0.01 sec)
mysql> show engine innodb status\G
BUFFER POOL AND MEMORY
----------------------
Total memory allocated 274726912; in additional pool allocated 0
Dictionary memory allocated 4055091
Buffer pool size 16383
Free buffers 1
Database pages 15673
Old database pages 5765
Modified db pages 521
Pending reads 0
Pending writes: LRU 0, flush list 0, single page 0
Pages made young 27497746, not young 0
0.00 youngs/s, 0.00 non-youngs/s
Pages read 6346456, created 1902566, written 372381712
0.00 reads/s, 0.37 creates/s, 27.75 writes/s
Buffer pool hit rate 1000 / 1000, young-making rate 0 / 1000 not 0 / 1000
Pages read ahead 0.00/s, evicted without access 0.00/s, Random read ahead 0.00/s
LRU len: 15673, unzip_LRU len: 0
I/O sum[1107]:cur[0], unzip sum[0]:cur[0]
命中率 Innodb_buffer_pool_read_requests - Innodb_buffer_pool_reads) / Innodb_buffer_pool_read_requests * 100%
170965099291-5392513/170965099291 × 100% = 99.99%
* InnoDB 字典信息緩存 InnoDB Additional Memory Pool(innodb_additional_mem_pool_size):
InnoDB 字典信息緩存主要用來存放 InnoDB 存儲引擎的字典信息以及一些 internal 的共享數據結構信息。因此其大小也與系統中所使用的 InnoDB 存儲引擎表的數量有較大關係。不過,若是咱們經過 innodb_additional_mem_pool_size 參數所設置的內存大小不夠,InnoDB 會自動申請更多的內存,並在 MySQL 的 Error Log 中記錄警告信息。
global級別,不可動態變動 Default 8M
設置InnoDB存放數據庫字典信息的Buffer大小
推薦配置:50M
3、查看統計
1.查看各參數內存配置方式
#全局共享內存 9個變量
show variables like 'innodb_buffer_pool_size'; /* InnoDB 數據和索引緩存(InnoDB Buffer Pool) */
show variables like 'innodb_additional_mem_pool_size'; /* InnoDB 字典信息緩存(InnoDB Additional Memory Pool)*/
show variables like 'innodb_log_buffer_size'; /* InnoDB 日誌緩衝區(InnoDB Log Buffer) */
show variables like 'binlog_cache_size'; /* 二進制日誌緩衝區(Binlog Buffer)*/
show variables like 'thread_cache_size'; /* 鏈接線程緩存(Thread Cache)*/
show variables like 'query_cache_size'; /* 查詢緩存(Query Cache)*/
show variables like 'table_open_cache'; /* 表緩存(Table Cache) */
show variables like 'table_definition_cache'; /* 表定義信息緩存(Table definition Cache) */
show variables like 'key_buffer_size'; /* MyISAM索引緩存(Key Buffer) */
#最大線程數
show variables like 'max_connections';
#線程獨享內存 6個變量
show variables like 'thread_stack'; /* 線線程棧信息使用內存(thread_stack) */
show variables like 'sort_buffer_size'; /* 排序使用內存(sort_buffer_size) */
show variables like 'join_buffer_size'; /* Join操做使用內存(join_buffer_size) */
show variables like 'read_buffer_size'; /* 順序讀取數據緩衝區使用內存(read_buffer_size) */
show variables like 'read_rnd_buffer_size'; /* 隨機讀取數據緩衝區使用內存(read_rnd_buffer_size) */
show variables like 'tmp_table_size'; /* 臨時表使用內存(tmp_table_size) ,我實際計算把tmp_table_size放入全局共享內*/
也能夠經過系統變量的方式直接獲取
select @@key_buffer_size;
select @@max_connections
2.mysql內存計算公式
mysql使用的內存 = 全局共享內存+最大線程數×線程獨享內存
mysql used mem=innodb_buffer_pool_size+innodb_additional_mem_pool_size+innodb_log_buffer_size+binlog_cache_size+thread_cache_size+query_cache_size+table_open_cache+table_definition_cache+key_buffer_size
+max_connections*(
thread_stack+sort_buffer_size+join_buffer_size+read_buffer_size+read_rnd_buffer_size+tmp_table_size)
SET @kilo_bytes=1024;
SET @mega_bytes=@kilo_bytes*1024;
SET @giga_bytes=@mega_bytes*1024;
SELECT (@@innodb_buffer_pool_size+@@innodb_additional_mem_pool_size+@@innodb_log_buffer_size+@@binlog_cache_size+@@thread_cache_size+@@query_cache_size+@@table_open_cache+@@table_definition_cache+@@key_buffer_size+@@max_connections*(@@thread_stack+@@sort_buffer_size+@@join_buffer_size+@@read_buffer_size+@@read_rnd_buffer_size+@@tmp_table_size))/@giga_bytes AS MAX_MEMORY_GB;
這個理論最大的內存使用量,在5.5版本中tmp_table_size默認是16M,按默認u自大鏈接數151計算,光線程獨享的臨時表佔據的空間都是2416M,我實際計算把tmp_table_size放入全局共享內
個人計算公式
mysql使用的內存 = 全局共享內存+最大線程數×線程獨享內存
mysql used mem=innodb_buffer_pool_size+innodb_additional_mem_pool_size+innodb_log_buffer_size+binlog_cache_size+thread_cache_size+query_cache_size+table_open_cache+table_definition_cache+key_buffer_size+tmp_table_size
+max_connections*(
thread_stack+sort_buffer_size+join_buffer_size+read_buffer_size+read_rnd_buffer_size)
SET @kilo_bytes=1024; SET @mega_bytes=@kilo_bytes*1024; SET @giga_bytes=@mega_bytes*1024; SELECT (@@innodb_buffer_pool_size+@@innodb_additional_mem_pool_size+@@innodb_log_buffer_size+@@binlog_cache_size+@@thread_cache_size+@@query_cache_size+@@table_open_cache+@@table_definition_cache+@@key_buffer_size+@@tmp_table_size+@@max_connections*(@@thread_stack+@@sort_buffer_size+@@join_buffer_size+@@read_buffer_size+@@read_rnd_buffer_size))/@giga_bytes AS MAX_MEMORY_GB;
這樣計算出來靠譜多了。
4.配置模板
##按內存4G,最大鏈接數1024個計算
#session
thread_stack = 192K #default
sort_buffer_size = 8M
join_buffer_size = 8M
read_buffer_size = 4M
read_rnd_buffer_size = 8M
#net_buffer_lenth = 16K #default
bulk_insert_buffer_size = 8M #default
tmp_table_size = 64M
max_heap_table_size = 64M
#global
key_buffer_size = 8M #default
query_cache_size = 16M
thread_cache_size = 8
table_open_cache = 2048
table_definition_cache = 2048
binlog_cache_size = 2M
innodb_buffer_pool_size = 2048M
innodb_additional_mem_pool_size = 50M
innodb_log_buffer_size = 8M #default
MariaDB [(none)]> SELECT (@@innodb_buffer_pool_size+@@innodb_additional_mem_pool_size+@@innodb_log_buffer_size+@@binlog_cache_size+@@thread_cache_size+@@query_cache_size+@@table_open_cache+@@table_definition_cache+@@key_buffer_size+@@tmp_table_size+@@max_connections*(@@thread_stack+@@sort_buffer_size+@@join_buffer_size+@@read_buffer_size+@@read_rnd_buffer_size))/@giga_bytes AS MAX_MEMORY_GB;
+---------------+
| MAX_MEMORY_GB |
+---------------+
| 30.3320 |
+---------------+
1 row in set (0.00 sec)
connection達到最大的時候,會把內存撐爆
全局
MariaDB [(none)]> SELECT (@@innodb_buffer_pool_size+@@innodb_additional_mem_pool_size+@@innodb_log_buffer_size+@@binlog_cache_size+@@thread_cache_size+@@query_cache_size+@@table_open_cache+@@table_definition_cache+@@key_buffer_size+@@tmp_table_size)/@giga_bytes AS MAX_MEMORY_GB;+---------------+
| MAX_MEMORY_GB |
+---------------+
| 2.1445 |
+---------------+
1 row in set (0.00 sec)
單個session
MariaDB [(none)]> SELECT (@@thread_stack+@@sort_buffer_size+@@join_buffer_size+@@read_buffer_size+@@read_rnd_buffer_size)/@giga_bytes AS MAX_MEMORY_GB;
+---------------+
| MAX_MEMORY_GB |
+---------------+
| 0.0275 |
+---------------+
0.0275*1024 = 28.1600
這個是極端狀況,每一個線程都把內存吃完,達到最大線程。
5.查看mysql使用的內存狀況
1)TOP M
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
7091 mysql 20 0 2884828 243124 6056 S 0.000 3.012 0:01.90 mysqld
VIRT 進程使用的虛擬內存總量,單位kb。VIRT=SWAP+RES
RES 進程使用的、未被換出的物理內存大小,單位kb。RES=CODE+DATA
SHR 共享內存大小,單位kb
2)pidstat
pidstat -C mysqld -r
Linux 3.11.10-7-desktop (MyOpenSUSE) 05/30/14 _x86_64_ (4 CPU)
23:07:32 PID minflt/s majflt/s VSZ RSS %MEM Command
23:07:32 6650 0.61 0.00 11900 1640 0.02 mysqld_safe
23:07:32 7091 4.03 0.00 2884828 245720 3.04 mysqld
# pidstat -p 7091 -r 1 10
Linux 3.11.10-7-desktop (MyOpenSUSE) 05/30/14 _x86_64_ (4 CPU)
23:07:59 PID minflt/s majflt/s VSZ RSS %MEM Command
23:08:00 7091 0.00 0.00 2884828 245720 3.04 mysqld
23:08:01 7091 0.00 0.00 2884828 245720 3.04 mysqld
3)pmap
pmap 7091
2645064K writable-private, 238916K readonly-private, 848K shared, and 245980K referenced
3.Python寫一個統計程序
# coding=utf8
'''
Created on May 27, 2014
@author: jin
'''
import time, MySQLdb
MysqlIP = '127.0.0.1'
MysqlUser = 'puser'
MysqlPassword = '123.com'
InnoDBMemList = ['innodb_buffer_pool_size','innodb_additional_mem_pool_size','innodb_log_buffer_size','binlog_cache_size','thread_cache_size','query_cache_size','table_open_cache','table_definition_cache','key_buffer_size','tmp_table_size']
SingeThreadMemList = ['thread_stack','sort_buffer_size','join_buffer_size','read_buffer_size','read_rnd_buffer_size']
conn=MySQLdb.connect(host=MysqlIP,user=MysqlUser,passwd=MysqlPassword,db="mysql",charset="utf8")
cursor = conn.cursor()
def main():
InnoDBMemNumList=[]
for i in InnoDBMemList:
SQL = "select @@"+i
n = cursor.execute(SQL)
for row in cursor.fetchall():
InnoDBMemNumList.append(row[0])
InnoDBMemNumTotal = sum(InnoDBMemNumList)
SingeThreadMemNumList=[]
for i in SingeThreadMemList:
SQL = "select @@"+i
n = cursor.execute(SQL)
for row in cursor.fetchall():
SingeThreadMemNumList.append(row[0])
SingeThreadMemTotal = sum(SingeThreadMemNumList)
n=cursor.execute("select @@max_connections")
for row in cursor.fetchall():
ThreadNumber = row[0]
kilo_bytes = 1024;
mega_bytes = kilo_bytes*1024
giga_bytes = mega_bytes*1024
PGA=ThreadNumber*SingeThreadMemTotal
TotalMen = float(InnoDBMemNumTotal+PGA)
print "Mysql memory information:\nMax Connections:%s\nSGA:%sM\nPGA:%sM\nTotal Used Memory:%sM\n" % (ThreadNumber/mega_bytes,InnoDBMemNumTotal/mega_bytes,PGA/mega_bytes,TotalMen/mega_bytes)
if __name__ == '__main__': main()