top
Loading...
7.5.5.MySQL如何使用內存
7.5.5. MySQL如何使用內存

下面的列表中列出了mysqld服務器使用內存的一些方法。在適用的地方,給出了內存相關的系統變量名:

·         鍵緩存(變量key_buffer_size)被所有線程共享;服務器使用的其它緩存則根據需要分配。參見7.5.2節,“調節服務器參數”。

·         每個連接使用具體線程的空間:

o        堆棧(默認64KB,變量thread_stack)

o        連接緩存區(變量net_buffer_length)

o        結果緩存區(變量net_buffer_length)

連接緩存區和結果緩存區可以根據需要動態擴充到max_allowed_packet。當某個查詢運行時,也為當前查詢字符串分配內存。

·         所有線程共享相同的基本內存。

·         只有壓縮MyISAM表映射到內存。這是因為4GB32位內存空間不足以容納大多數大表。當64位地址空間的系統變得越來越普遍后,我們可以增加常規的內存映射支持。

·         對表進行順序掃描的請求將分配一個緩存區(變量read_buffer_size)

·         當按任意順序讀取行時(例如,按照排序順序),將分配一個隨機讀 緩存區(變量read_rnd_buffer_size)以避免硬盤搜索。

·         所有聯合在一個令牌內完成,并且大多數聯合甚至可以不用臨時表即可以完成。大多數臨時表是基于內存的(HEAP)表。具有大的記錄長度的臨時表 (所有列的長度的和)或包含BLOB列的表存儲在硬盤上。

如果某個內部heap(堆積)表大小超過tmp_table_sizeMySQL可以根據需要自動將內存中的heap表改為基于硬盤的MyISAM表。還可以通過設置mysqldtmp_table_size選項來增加臨時表的大小,或設置客戶程序中的SQL選項SQL_BIG_TABLE。參見13.5.3節,“SET語法”。

·         進行排序的大多數請求將分配一個排序緩存區,并根據結果集的大小為兩個臨時文件分配零。參見A.4.4節,“MySQL將臨時文件儲存在哪里”。

·         幾乎所有解析和計算在局部內存中完成。小項目不需要內存,因此避免了普通的慢內存分配和釋放。只為不期望的大字符串分配內存;使用函數malloc()free()來完成。

·         對于每個打開的MyISAM表,索引文件打開一次;數據文件為每個并行運行的線程打開一次。對于每個并行線程,將分配一個表結構、一個每個列的列結構和大小為3 * N的緩存區(其中N是最大行的長度,而不是計算BLOB)。一個BLOB列需要58個字節加上BLOB數據的長度。MyISAM 存儲引擎維護一個額外的行緩存區供內部應用。

·         對于每個具有BLOB列的表,將對緩存區進行動態擴大以讀入大的BLOB 值。如果你掃描一個表,則分配一個與最大的BLOB值一樣大的緩存區。

·         所有使用的表的句柄結構保存在高速緩存中并以FIFO管理。默認情況,高速緩存有64個入口。如果某個表同時被兩個運行的線程使用,高速緩存則為該提供兩個入口。參見7.4.9節,“MySQL如何打開和關閉表”。

·         當并行執行的線程結束時,FLUSH TABLE語句或mysqladmin flush-table命令可以立即關閉所有不使用的表并將所有使用中的表標記為已經關閉。這樣可以有效釋放大多數使用中的內存。FLUSH TABLE在關閉所有表之前不返回結果。

ps和其它系統狀態程序可以報導mysqld使用很多內存。這可以是在不同的內存地址上的線程棧造成的。例如,Solaris版本的ps將棧間未用的內存算作已用的內存。你可以通過用swap -s檢查可用交換區來驗證它。我們用商業內存漏洞探查器測試了mysqld,因此應該有沒有內存漏洞。

作者:mysql.com
來源:http://dev.mysql.com/doc/refman/5.1/zh/optimization.html
北斗有巢氏 有巢氏北斗