MySQL內存及虛擬內存優化設置

mysql 優化調試命令html

一、mysqld --verbose --helpmysql

這個命令生成全部mysqld選項和可配置變量的列表算法

二、經過鏈接它並執行這個命令,能夠看到實際上使用的變量的值:sql

mysql> SHOW VARIABLES;

還能夠經過下面的語句看到運行服務器的統計和狀態指標:shell

mysql>SHOW STATUS;

使用mysqladmin還能夠得到系統變量和狀態信息:數據庫

shell> mysqladmin variables
shell> mysqladmin extended-status

shell> mysqladmin flush-table 命令能夠當即關閉全部不使用的表並將全部使用中的表標記爲已經關閉,這樣能夠有效釋放大多數使用中的內存。FLUSH TABLE在關閉全部表以前不返回結果。緩存

swap -s檢查可用交換區安全

mysql內存計算公式服務器

mysql used mem = key_buffer_size + query_cache_size + tmp_table_size
+ innodb_buffer_pool_size + innodb_additional_mem_pool_size
+ innodb_log_buffer_size
+ max_connections * (
read_buffer_size + read_rnd_buffer_size
+ sort_buffer_size+ join_buffer_size
+ binlog_cache_size + thread_stack
)數據結構

在mysql 中輸入以下命令,可自動計算本身的當前配置最大的內存消耗

SHOW VARIABLES LIKE 'innodb_buffer_pool_size';
SHOW VARIABLES LIKE 'innodb_additional_mem_pool_size';
SHOW VARIABLES LIKE 'innodb_log_buffer_size';
SHOW VARIABLES LIKE 'thread_stack';
SET @kilo_bytes = 1024;
SET @mega_bytes = @kilo_bytes * 1024;
SET @giga_bytes = @mega_bytes * 1024;
SET @innodb_buffer_pool_size = 2 * @giga_bytes;
SET @innodb_additional_mem_pool_size = 16 * @mega_bytes;
SET @innodb_log_buffer_size = 8 * @mega_bytes;
SET @thread_stack = 192 * @kilo_bytes;
SELECT
( @@key_buffer_size + @@query_cache_size + @@tmp_table_size
+ @innodb_buffer_pool_size + @innodb_additional_mem_pool_size
+ @innodb_log_buffer_size
+ @@max_connections * (
@@read_buffer_size + @@read_rnd_buffer_size + @@sort_buffer_size
+ @@join_buffer_size + @@binlog_cache_size + @thread_stack
) ) / @giga_bytes AS MAX_MEMORY_GB;

 

 

mysql關鍵參數設置

Mysqld 數據庫的參數設置有兩種類型,

 

一種是全局參數,影響服務器的全局操做;

另外一種是會話級參數,隻影響當前的客戶端鏈接的相關操做。

 

服務器啓動時,全部全局參數都初始化爲默認值。能夠在初始化文件或命令行中指定的選項來更改這些默認值。服務器啓動後,經過鏈接服務器並執行 SET GLOBAL var_name 語句能夠更改動態全局參數。要想更改全局參數,必須具備 SUPER 權限。全局參數的修改只對新的鏈接生效,已有的客戶端鏈接並不會生效。

 

服務器還能夠爲每一個客戶端鏈接維護會話級參數,客戶端鏈接時使用相應全局參數的當前值對客戶端會話參數進行初始化。客戶能夠經過 SET SESSION var_name 語句來更改動態會話參數。設置會話級參數不須要特殊權限,但每一個客戶端能夠只更改本身的會話級參數,不能更改其它客戶的會話級參數。

不指定設置的參數類型時,默認設置的是會話級參數。

 


(1)、max_connections:
容許的同時客戶的數量。增長該值增長 mysqld 要求的文件描述符的數量。這個數字應該增長,不然,你將常常看到 too many connections 錯誤。 默認數值是100,我把它改成1024 。

(2)、record_buffer:
每一個進行一個順序掃描的線程爲其掃描的每張表分配這個大小的一個緩衝區。若是你作不少順序掃描,你可能想要增長該值。默認數值是131072(128k),我把它改成16773120 (16m)

(3)、key_buffer_size:

爲了最小化磁盤的 I/O , MyISAM 存儲引擎的表使用鍵高速緩存來緩存索引,這個鍵高速緩存的大小則經過 key-buffer-size 參數來設置。若是應用系統中使用的表以 MyISAM 存儲引擎爲主,則應該適當增長該參數的值,以便儘量的緩存索引,提升訪問的速度。


索引塊是緩衝的而且被全部的線程共享。key_buffer_size是用於索引塊的緩衝區大小,增長它可獲得更好處理的索引(對全部讀和多重寫),到你能負擔得起那樣多。若是你使它太大,系統將開始換頁而且真的變慢了。默認數值是8388600(8m),個人mysql主機有2gb內存,因此我把它改成 402649088(400mb)。

默認狀況下,全部的索引都使用相同的鍵高速緩存,當訪問的索引不在緩存中時,使用 LRU ( Least Recently Used 最近最少使用)算法來替換緩存中最近最少使用的索引塊。爲了進一步避免對鍵高速緩存的爭用,從 MySQL5.1 開始,能夠設置多個鍵高速緩存,併爲不一樣的索引鍵指定使用的鍵高速緩存。下面的例子演示如何修改高速鍵緩存的值,如何設置多個鍵高速緩存,以及如何爲不一樣的索引指定不一樣的緩存:

顯示當前的參數大小,爲16M:

mysql> show variables like 'key_buffer_size';

+-----------------+-------+

| Variable_name | Value |

+-----------------+-------+

| key_buffer_size | 16384 |

+-----------------+-------+

1 row in set (0.00 sec)

修改參數值到200M:

mysql> set global key_buffer_size=204800;

Query OK, 0 rows affected (0.00 sec)

mysql> show variables like 'key_buffer_size';

+-----------------+--------+

| Variable_name | Value |

+-----------------+--------+

| key_buffer_size | 204800 |

+-----------------+--------+

1 row in set (0.00 sec)

上面介紹的是默認的鍵緩存,下面介紹如何設置多個鍵緩存:

設置 hot_cache 的鍵緩存 100M , cold_cache 的鍵緩存 100M ,另外還有 200M 的默認的鍵緩存。若是索引不指定鍵緩存,則會放在默認的鍵緩存中。

mysql> set global hot_cache.key_buffer_size=102400;

Query OK, 0 rows affected (0.00 sec)

mysql> set global cold_cache.key_buffer_size= 1024 00;

Query OK, 0 rows affected (0.01 sec)

mysql> show variables like 'key_buffer_size';

+-----------------+--------+

| Variable_name | Value |

+-----------------+--------+

| key_buffer_size | 204800 |

+-----------------+--------+

1 row in set (0.00 sec)

若是要顯示設置的多鍵緩存的值,可使用:

mysql> SELECT @@global.hot_cache.key_buffer_size;

+------------------------------------+

| @@global.hot_cache.key_buffer_size |

+------------------------------------+

| 102400 |

+------------------------------------+

1 row in set (0.03 sec)

mysql> SELECT @@global.cold_cache.key_buffer_size;

+-------------------------------------+

| @@global.cold_cache.key_buffer_size |

+-------------------------------------+

| 102400 |

+-------------------------------------+

1 row in set (0.00 sec)

指定不一樣的索引使用不一樣的鍵緩存:

mysql> CACHE INDEX test1 in hot_cache;

+------------+--------------------+----------+----------+

| Table | Op | Msg_type | Msg_text |

+------------+--------------------+----------+----------+

| test .test1 | assign_to_keycache | status | OK |

+------------+--------------------+----------+----------+

1 row in set (0.00 sec)

mysql> CACHE INDEX test2 in hot_cache;

+------------+--------------------+----------+----------+

| Table | Op | Msg_type | Msg_text |

+------------+--------------------+----------+----------+

| test .test2 | assign_to_keycache | status | OK |

+------------+--------------------+----------+----------+

1 row in set (0.00 sec)

一般在數據庫剛剛啓動的時候,須要等待數據庫熱起來,也就是等待數據被緩存到緩存區中,這段時間數據庫會由於 buffer 的命中率低而致使應用的訪問效率不高。使用鍵高速緩存的時候,能夠經過命令將索引預加載到緩存區中,大大縮短了數據庫預熱的時間。具體的操做方式是:

mysql> LOAD INDEX INTO CACHE test1,test2 IGNORE LEAVES;

+------------+--------------+----------+----------+

| Table | Op | Msg_type | Msg_text |

+------------+--------------+----------+----------+

| test .test1 | preload_keys | status | OK |

| test .test2 | preload_keys | status | OK |

+------------+--------------+----------+----------+

2 rows in set (3.89 sec)

若是已經使用 CACHE INDEX 語句爲索引分配了一個鍵高速緩衝,預加載能夠將索引塊放入該緩存,不然,索引塊將被加載到默認的鍵高速緩衝。

 


4)、back_log:
要求 mysql 能有的鏈接數量。當主要mysql線程在一個很短期內獲得很是多的鏈接請求,這就起做用,而後主線程花些時間(儘管很短)檢查鏈接而且啓動一個新線程。
back_log 值指出在mysql暫時中止回答新請求以前的短期內多少個請求能夠被存在堆棧中。只有若是指望在一個短期內有不少鏈接,你須要增長它,換句話說,這值對到來的tcp/ip鏈接的偵聽隊列的大小。你的操做系統在這個隊列大小上有它本身的限制。試圖設定back_log高於你的操做系統的限制將是無效的。
當你觀察你的主機進程列表,發現大量 264084 | unauthenticated user | xxx.xxx.xxx.xxx | null | connect | null | login | null 的待鏈接進程時,就要加大 back_log 的值了。默認數值是50,我把它改成500。

(5)、interactive_timeout:
服務器在關閉它前在一個交互鏈接上等待行動的秒數。一個交互的客戶被定義爲對 mysql_real_connect()使用 client_interactive 選項的客戶。 默認數值是28800,我把它改成7200。


(6)、sort_buffer:
每一個須要進行排序的線程分配該大小的一個緩衝區。增長這值加速order by或group by操做。默認數值是2097144(2m),我把它改成 16777208 (16m)。

(7)、table_cache:
爲全部線程打開表的數量。增長該值能增長mysqld要求的文件描述符的數量。mysql對每一個惟一打開的表須要2個文件描述符。默認數值是64,我把它改成512。

(8)、thread_cache_size:
能夠複用的保存在中的線程的數量。若是有,新的線程從緩存中取得,當斷開鏈接的時候若是有空間,客戶的線置在緩存中。若是有不少新的線程,爲了提升性能能夠這個變量值。經過比較 connections 和 threads_created 狀態的變量,能夠看到這個變量的做用。我把它設置爲 80。

(9)mysql的搜索功能
用mysql進行搜索,目的是能不分大小寫,又能用中文進行搜索
只需起動mysqld時指定 --default-character-set=gb2312

(10)、wait_timeout:
服務器在關閉它以前在一個鏈接上等待行動的秒數。 默認數值是28800,我把它改成7200。

 

(11)、innodb_thread_concurrency:
你的服務器CPU有幾個就設置爲幾,默認爲8。

 

(12)、query_cache_size  與 query_cache_limit

QueryCache 以後所帶來的負面影響:
a) Query 語句的hash 運算以及hash 查找資源消耗。當咱們使用Query Cache 以後,每條SELECT
類型的Query 在到達MySQL 以後,都須要進行一個hash 運算而後查找是否存在該Query 的
Cache,雖然這個hash 運算的算法可能已經很是高效了,hash 查找的過程也已經足夠的優化
了,對於一條Query 來講消耗的資源確實是很是很是的少,可是當咱們每秒都有上千甚至幾千
條Query 的時候,咱們就不能對產生的CPU 的消耗徹底忽視了。
b) Query Cache 的失效問題。若是咱們的表變動比較頻繁,則會形成Query Cache 的失效率很是
高。這裏的表變動不只僅指表中數據的變動,還包括結構或者索引等的任何變動。也就是說我
們每次緩存到Query Cache 中的Cache 數據可能在剛存入後很快就會由於表中的數據被改變而被
清除,而後新的相同Query 進來以後沒法使用到以前的Cache。
c) Query Cache 中緩存的是Result Set ,而不是數據頁,也就是說,存在同一條記錄被Cache 多
次的可能性存在。從而形成內存資源的過渡消耗。固然,可能有人會說咱們能夠限定Query
Cache 的大小啊。是的,咱們確實能夠限定Query Cache 的大小,可是這樣,Query Cache 就很
容易形成由於內存不足而被換出,形成命中率的降低。

 

QueryCache 的正確使用:

雖然Query Cache 的使用會存在一些負面影響,可是咱們也應該相信其存在是一定有必定價值。我
們徹底不用由於Query Cache 的上面三個負面影響就徹底失去對Query Cache 的信心。只要咱們理解了
Query Cache 的實現原理,那麼咱們就徹底能夠經過必定的手段在使用Query Cache 的時候揚長避短,重
發發揮其優點,並有效的避開其劣勢。
首先,咱們須要根據Query Cache 失效機制來判斷哪些表適合使用Query 哪些表不適合。因爲Query
Cache 的失效主要是由於Query 所依賴的Table 的數據發生了變化,形成Query 的Result Set 可能已經
有所改變而形成相關的Query Cache 所有失效,那麼咱們就應該避免在查詢變化頻繁的Table 的Query 上
使用,而應該在那些查詢變化頻率較小的Table 的Query 上面使用。MySQL 中針對Query Cache 有兩個專
用的SQL Hint(提示):SQL_NO_CACHE 和SQL_CACHE,分別表明強制不使用Query Cache 和強制使用
Query Cache。咱們徹底能夠利用這兩個SQL Hint,讓MySQL 知道咱們但願哪些SQL 使用Query Cache 而
哪些SQL 就不要使用了。這樣不只可讓變化頻繁Table 的Query 浪費Query Cache 的內存,同時還能夠
減小Query Cache 的檢測量。
其次,對於那些變化很是小,大部分時候都是靜態的數據,咱們能夠添加SQL_CACHE 的SQL Hint,
強制MySQL 使用Query Cache,從而提升該表的查詢性能。
最後,有些SQL 的Result Set 很大,若是使用Query Cache 很容易形成Cache 內存的不足,或者將
以前一些老的Cache 沖刷出去。對於這一類Query 咱們有兩種方法能夠解決,一是使用SQL_NO_CACHE 參
數來強制他不使用Query Cache 而每次都直接從實際數據中去查找, 另外一種方法是經過設定
「query_cache_limit」參數值來控制Query Cache 中所Cache 的最大Result Set ,系統默認爲
1M(1048576)。當某個Query 的Result Set 大於「query_cache_limit」所設定的值的時候,Query
Cache 是不會Cache 這個Query 的。

(13)、innodb_buffer_pool_size

innodb_buffer_pool_size 定義了 InnoDB 存儲引擎的表數據和索引數據的最大內存緩衝區大小。和 MyISAM 存儲引擎不一樣, MyISAM 的 key_buffer_size 只能緩存索引鍵,而 innodb_buffer_pool_size 卻能夠緩存數據塊和索引鍵。適當的增長這個參數的大小,能夠有效的減小 InnoDB 類型的表的磁盤 I/O 。在一個以 InnoDB 爲主的專用數據庫服務器上,能夠考慮把該參數設置爲物理內存大小的 60%-80%

 

InnoDB佔用的內存,除innodb_buffer_pool_size用於存儲頁面緩存數據外,另外正常狀況下還有大約8%的開銷,主要用在每一個緩存頁幀的描述、adaptive hash等數據結構,若是不是安全關閉,啓動時還要恢復的話,還要另開大約12%的內存用於恢復,二者相加就有差很少21%的開銷。

這樣,12G的innodb_buffer_pool_size,最多的時候InnoDB就可能佔用到14.5G(12G X 21%)的內存,再加上操做系統用的幾百M,近千個線程堆棧,就差很少16G了。

 

MAX_QUERIES_PER_HOUR 用來限制用戶每小時運行的查詢數量:

mysql> grant all on dbname。* to db@localhost identified by 「123456」 with max_connections_per_hour 5;

(db用戶在dbname的數據庫上控制用戶每小時打開新鏈接的數量爲5個)

 

MAX_USER_CONNECTIONS 限制有多少用戶鏈接MYSQL服務器:

mysql> grant all on dbname。* to db@localhost identified by 「123456」 with max_user_connections 2;

(db用戶在dbname的數據庫帳戶一次能夠同時鏈接的最大鏈接數爲2個)


MAX_UPDATES_PER_HOUR 用來限制用戶每小時的修改數據庫數據的數量:

mysql> grant all on dbname。* to db@localhost identified by 「123456」 with max_updates_per_hour 5;

(db用戶在dbname的數據庫上控制用戶每小時修改更新數據庫的次數爲5次)

MAX_USER_CONNECTIONS 用來限制用戶每小時的修改數據庫數據的數量:

mysql> grant all on dbname。* to db@localhost identified by 「123456」

With MAX_QUERIES_PER_HOUR 20 ;指mysql單個用戶的最大鏈接數

(db用戶在dbname的數據庫上控制用戶每小時的鏈接數爲20個)

 

調優舉例

針對my.cnf文件進行優化:

[mysqld]

skip-locking(取消文件系統的外部鎖)

skip-name-resolve(不進行域名反解析,注意由此帶來的權限/受權問題)
key_buffer_size = 256M(分配給MyISAM索引緩存的內存總數)對於內存在4GB左右的服務器該參數可設置爲256M或384M。
  注意:該參數值設置的過大反而會是服務器總體效率下降!
  max_allowed_packet = 4M(容許最大的包大小)
  thread_stack = 256K(每一個線程的大小)
  table_cache = 128K(緩存可重用的線程數)
  back_log = 384(臨時中止響應新請求前在短期內能夠堆起多少請求,若是你須要在短期內容許大量鏈接,能夠增長該數值)
  sort_buffer_size = 2M(分配給每一個線程中處理排序)
  read_buffer_size = 2M(讀取的索引緩衝區大小)
  join_buffer_size = 2M(分配給每一個線程中處理掃描錶鏈接及索引的內存)
  myisam_sort_buffer_size = 64M(myisam引擎排序緩衝區的大小)
  table_cache = 512(緩存數據表的數量,避免重複打開表的開銷)
  thread_cache_size = 64(緩存可重用線程數,見笑建立新線程的開銷)
  query_cache_size = 64M(控制分配給查詢緩存的內存總量)
  tmp_table_size = 256M(指定mysql緩存的內存大小)
  max_connections = 768(最大鏈接數)指mysql整個的最大鏈接數
max_connect_errors = 10000(最大鏈接錯誤數據)
  wait_timeout = 10(超時時間,能夠避免攻擊)
  thread_concurrency = 8(根據cpu數量來設置)
  skip-bdb 禁用沒必要要的引擎
  skip-networking(關閉mysql tcp/ip鏈接方式)
  Log-slow-queries = /var/log/mysqlslowqueries.log
  long_query_time = 4(設定慢查詢的時間)
  skip-host-cache(提升mysql速度的)
  open_files_limit = 4096(打開文件數)
interactive_timeout = 10(服務器在關閉它前在一個交互鏈接上等待行動的秒數)
max_user_connections = 500(最大用戶鏈接數)

 

key_buffer_size                 默認爲218       調到128最佳

query_cache_size  

tmp_table_size                  默認爲16M        調到64-256最掛

innodb_thread_concurrency=8       你的服務器CPU有幾個就設置爲幾,默認爲8

 

table_cache=1024 物理內存越大,設置就越大.默認爲2402,調到512-1024最佳
innodb_additional_mem_pool_size=8M   默認爲2M
innodb_flush_log_at_trx_commit=0 等到innodb_log_buffer_size列隊滿後再統一儲存,默認爲1
innodb_log_buffer_size=4M          默認爲1M

read_buffer_size=4M                   默認爲64K
read_rnd_buffer_size   隨機讀 緩存區  默認爲256K
sort_buffer_size=32M                   默認爲256K
max_connections=1024                 默認爲1210

thread_cache_size=120             默認爲60

性能測試

一、mysql 自帶測試工具

shell> perl -MCPAN -e shell
cpan> install DBI
cpan> install DBD::mysql

shell> cd sql-bench

shell> perl run-all-tests --server=server_name

server_name是一個支持的服務器。要得到全部選項和支持的服務器,調用命令:

shell> perl run-all-tests --help

二、mysqlreport

 http://hackmysql.com/mysqlreport

參考文檔

http://dev.mysql.com/doc/refman/5.1/zh/optimization.html

http://hackmysql.com/tools

http://www.imysql.cn/

相關文章
相關標籤/搜索