mysql內存使用分析(一)

author:skate
time:2012/02/16
 
mysql內存使用分析
 
從內存的使用方式來說,MySQL數據庫的內存使用主要分為以下兩類
 
1.線程獨享內存
2.全局共享內存
 
1.線程獨享內存
 
在MySQL 中,線程獨享內存主要用於各客戶端連接線程存儲各種操作的獨享數據,
如線程棧信息,分組排序操作,數據讀寫緩沖,結果集暫存等等,而且大多數可
以通過相關參數來控制內存的使用量。
 
線程棧信息使用內存(thread_stack):
主要用來存放每一個線程自身的標識信息,如線程id,線程運行時基本信息等等,
我們可以通過thread_stack 參數來設置為每一個線程棧分配多大的內存。
 
排序使用內存(sort_buffer_size):
MySQL 用此內存區域進行排序操作(filesort),完成客戶端的排序請求。當我們
設置的排序區緩存大小無法滿足排序實際所需內存的時候,MySQL 會將數據寫入磁
盤文件來完成排序。由於磁盤和內存的讀寫性能完全不在一個數量級,所以
sort_buffer_size參數對排序操作的性能影響絕對不可小視。排序操作的實現原理
請參考:MySQL Order By 的實現分析。
 
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 訪問,降低效率。
 
順序讀取數據緩沖區使用內存(read_buffer_size):
這部分內存主要用於當需要順序讀取數據的時候,如無法使用索引的情況下的全表
掃描,全索引掃描等。在這種時候,MySQL按照數據的存儲順序依次讀取數據塊,
每次讀取的數據快首先會暫存在read_buffer_size中,當buffer空間被寫滿或者全部
數據讀取結束後,再將buffer中的數據返回給上層調用者,以提高效率。
 
隨機讀取數據緩沖區使用內存(read_rnd_buffer_size):
和順序讀取相反,當MySQL進行非順序讀取(隨機讀取)數據塊的時候,會利用這個緩沖
區暫存讀取的數據。如根據索引信息讀取表數據,根據排序後的結果集與表進行Join等等。
總的來說,就是當數據塊的讀取需要滿足一定的順序的情況下,MySQL就需要產生隨機讀
取,進而使用到read_rnd_buffer_size 參數所設置的內存緩沖區。
 
連接信息及返回客戶端前結果集暫存使用內存(net_buffer_size):
這部分用來存放客戶端連接線程的連接信息和返回客戶端的結果集。當MySQL 開始產生
可以返回的結果集,會在通過網絡返回給客戶端請求線程之前,會先暫存在通過
net_buffer_size 所設置的緩沖區中,等滿足一定大小的時候才開始向客戶端發送,以提高網
絡傳輸效率。不過,net_buffer_size 參數所設置的僅僅隻是該緩存區的初始化大小,MySQL
會根據實際需要自行申請更多的內存以滿足需求,但最大不會超過max_allowed_packet 參數大小。
 
批量插入暫存使用內存(bulk_insert_buffer_size):
當我們使用如insert …values(…),(…),(…)… 的方式進行批量插入的時候,MySQL 會先將
提交的數據放如一個緩存空間中,當該緩存空間被寫滿或者提交完所有數據之後,MySQL 才會
一次性將該緩存空間中的數據寫入數據庫並清空緩存。此外,當我們進行LOAD DATA INFILE
 操作來將文本文件中的數據Load 進數據庫的時候,同樣會使用到此緩沖區。
 
臨時表使用內存(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。
 
上面所列舉的MySQL 線程獨享內存僅僅隻是所有線程獨享內存中的部分,並不是全部,
隻是這些可能對MySQL 的性能產生較大的影響,且可以通過系統參數進行調節。
 
由於以上內存都是線程獨享,極端情況下的內存總體使用量將是所有連接線程的總倍數。
所以在設置過程中一定要謹慎,切不可為瞭提升性能就盲目的增大各參數值,避免因為
內存不夠而產生Out Of Memory 異常或者是嚴重的Swap 交換反而降低整體性能。
 
 
 
 
 
—–end—–

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *