天天看點

mysql 線程 占用記憶體_MySQL記憶體使用-線程獨享

前言

在 MySQL 中,線程獨享記憶體主要用于各用戶端連接配接線程存儲各種操作的獨享資料,如線程棧資訊,分組排序操作,資料讀寫緩沖,結果集暫存等等,而且大多數可以通過相關參數來控制記憶體的使用量。

線程棧資訊使用記憶體(thread_stack)

主要用來存放每一個線程自身的辨別資訊,如線程id,線程運作時基本資訊等等,我們可以通過 thread_stack 參數來設定為每一個線程棧配置設定多大的記憶體。

排序使用記憶體(sort_buffer_size)

MySQL 用此記憶體區域進行排序操作(filesort),完成用戶端的排序請求。當我們設定的排序區緩存大小無法滿足排序實際所需記憶體的時候,MySQL 會将資料寫入磁盤檔案來完成排序。由于磁盤和記憶體的讀寫性能完全不在一個數量級,是以sort_buffer_size參數對排序操作的性能影響絕對不可小視。經常使用索引來完成排序操作。

Join操作使用記憶體(join_buffer_size)

應用程式經常會出現一些兩表(或多表)Join的操作需求,MySQL在完成某些 Join 需求的時候(all/index join),為了減少參與Join的“被驅動表”的讀取次數以提高性能,需要使用到 Join Buffer 來協助完成 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 交換反而降低整體性能。