經過根據服務器目前情況,修改Mysql的系統參數,達到合理利用服務器現有資源,最大合理的提升MySQL性能。html
32G內存、4個CPU,每一個CPU 8核。mysql
MySQL目前安裝,用的是MySQL默認的最大支持配置。拷貝的是my-huge.cnf.編碼已修改成UTF-8.具體修改及安裝MySQL,能夠參考<<Linux系統上安裝MySQL 5.5>>幫助文檔。算法
打開MySQL配置文件my.cnfsql
vi /etc/my.cnf數據庫 |
back_log=500緩存
back_log值指出在MySQL暫時中止回答新請求以前的短期內多少個請求能夠被存在堆棧中。也就是說,若是MySql的鏈接數據達到max_connections時,新來的請求將會被存在堆棧中,以等待某一鏈接釋放資源,該堆棧的數量即back_log,若是等待鏈接的數量超過back_log,將不被授予鏈接資源。將會報:unauthenticated user | xxx.xxx.xxx.xxx | NULL | Connect | NULL | login | NULL 的待鏈接進程時.安全 back_log值不能超過TCP/IP鏈接的偵聽隊列的大小。若超過則無效,查看當前系統的TCP/IP鏈接的偵聽隊列的大小命令:cat /proc/sys/net/ipv4/tcp_max_syn_backlog目前系統爲1024。對於Linux系統推薦設置爲小於512的整數。服務器 修改系統內核參數,)http://www.51testing.com/html/64/n-810764.html網絡 查看mysql 當前系統默認back_log值,命令:數據結構 show variables like 'back_log'; 查看當前數量 |
wait_timeout=1800(單位爲妙)
我對wait-timeout這個參數的理解:MySQL客戶端的數據庫鏈接閒置最大時間值。 說得比較通俗一點,就是當你的MySQL鏈接閒置超過必定時間後將會被強行關閉。MySQL默認的wait-timeout 值爲8個小時,能夠經過命令show variables like 'wait_timeout'查看結果值;。 設置這個值是很是有意義的,好比你的網站有大量的MySQL連接請求(每一個MySQL鏈接都是要內存資源開銷的 ),因爲你的程序的緣由有大量的鏈接請求空閒啥事也不幹,白白佔用內存資源,或者致使MySQL超過最大鏈接數歷來沒法新建鏈接致使「Too many connections」的錯誤。在設置以前你能夠查看一下你的MYSQL的狀態(可用show processlist),若是常常發現MYSQL中有大量的Sleep進程,則須要 修改wait-timeout值了。 interactive_timeout:服務器關閉交互式鏈接前等待活動的秒數。交互式客戶端定義爲在mysql_real_connect()中使用CLIENT_INTERACTIVE選項的客戶端。 wait_timeout:服務器關閉非交互鏈接以前等待活動的秒數。在線程啓動時,根據全局wait_timeout值或全局 interactive_timeout值初始化會話wait_timeout值,取決於客戶端類型(由mysql_real_connect()的鏈接選項CLIENT_INTERACTIVE定義). 這兩個參數必須配合使用。不然單獨設置wait_timeout無效 |
max_connections=3000
max_connections是指MySql的最大鏈接數,若是服務器的併發鏈接請求量比較大,建議調高此值,以增長並行鏈接數量,固然這創建在機器能支撐的狀況下,由於若是鏈接數越多,介於MySql會爲每一個鏈接提供鏈接緩衝區,就會開銷越多的內存,因此要適當調整該值,不能盲目提升設值。能夠過'conn%'通配符查看當前狀態的鏈接數量,以定奪該值的大小。 MySQL服務器容許的最大鏈接數16384; 查看系統當前最大鏈接數: show variables like 'max_connections'; |
max_user_connections=800
max_user_connections是指每一個數據庫用戶的最大鏈接 針對某一個帳號的全部客戶端並行鏈接到MYSQL服務的最大並行鏈接數。簡單說是指同一個帳號可以同時鏈接到mysql服務的最大鏈接數。設置爲0表示不限制。 目前默認值爲:0不受限制。 這兒順便介紹下Max_used_connections:它是指從此次mysql服務啓動到如今,同一時刻並行鏈接數的最大值。它不是指當前的鏈接狀況,而是一個比較值。若是在過去某一個時刻,MYSQL服務同時有1000個請求鏈接過來,而以後再也沒有出現這麼大的併發請求時,則Max_used_connections=1000.請注意與show variables 裏的max_user_connections的區別。默認爲0表示無限大。 查看max_user_connections值 show variables like 'max_user_connections'; |
thread_concurrency=64
thread_concurrency的值的正確與否, 對mysql的性能影響很大, 在多個cpu(或多核)的狀況下,錯誤設置了thread_concurrency的值, 會致使mysql不能充分利用多cpu(或多核), 出現同一時刻只能一個cpu(或核)在工做的狀況。 thread_concurrency應設爲CPU核數的2倍. 好比有一個雙核的CPU, 那thread_concurrency 的應該爲4; 2個雙核的cpu, thread_concurrency的值應爲8. 好比:根據上面介紹咱們目前系統的配置,可知道爲4個CPU,每一個CPU爲8核,按照上面的計算規則,這兒應爲:4*8*2=64 查看系統當前thread_concurrency默認配置命令: show variables like 'thread_concurrency'; |
skip-name-resolve
skip-name-resolve:禁止MySQL對外部鏈接進行DNS解析,使用這一選項能夠消除MySQL進行DNS解析的時間。但須要注意,若是開啓該選項,則全部遠程主機鏈接受權都要使用IP地址方式,不然MySQL將沒法正常處理鏈接請求! |
skip-networking建議被註釋掉,不要開啓
開啓該選項能夠完全關閉MySQL的TCP/IP鏈接方式,若是WEB服務器是以遠程鏈接的方式訪問MySQL數據庫服務器則不要開啓該選項!不然將沒法正常鏈接! |
default-storage-engine= InnoDB(設置InnoDB類型,另外還能夠設置MyISAM類型)
設置建立數據庫及表默認存儲類型 show table status like ‘tablename’顯示錶的當前存儲狀態值 查看MySQL有哪些存儲狀態及默認存儲狀態 show engines; 建立表並指定存儲類型 CREATE TABLE mytable (id int, title char(20)) ENGINE = INNODB; 修改表存儲類型: Alter table tableName engine =engineName
備註:設置完後把如下幾個開啓: # Uncomment the following if you are using InnoDB tables innodb_data_home_dir = /var/lib/mysql #innodb_data_file_path = ibdata1:1024M;ibdata2:10M:autoextend(要註釋掉,不然會建立一個新的把原來的替換的。) innodb_log_group_home_dir = /var/lib/mysql # You can set .._buffer_pool_size up to 50 - 80 % # of RAM but beware of setting memory usage too high innodb_buffer_pool_size = 1000M innodb_additional_mem_pool_size = 20M # Set .._log_file_size to 25 % of buffer pool size innodb_log_file_size = 500M innodb_log_buffer_size = 20M innodb_flush_log_at_trx_commit = 0 innodb_lock_wait_timeout = 50 設置完後必定記得把MySQL安裝目錄地址(咱們目前是默認安裝因此地址/var/lib/mysql/)下的ib_logfile0和ib_logfile1刪除掉。不然重啓MySQL起動失敗。 |
數據庫屬於IO密集型的應用程序,其主職責就是數據的管理及存儲工做。而咱們知道,從內存中讀取一個數據庫的時間是微秒級別,而從一塊普通硬盤上讀取一個 IO是在毫秒級別,兩者相差3個數量級。因此,要優化數據庫,首先第一步須要優化的就是IO,儘量將磁盤IO轉化爲內存IO。本文先從MySQL數據庫 IO相關參數(緩存參數)的角度來看看能夠經過哪些參數進行IO優化 |
啓動MySQL時就要分配而且老是存在的全局緩存。目前有:key_buffer_size(默認值:402653184,即384M)、innodb_buffer_pool_size(默認值:134217728即:128M)、innodb_additional_mem_pool_size(默認值:8388608即:8M)、innodb_log_buffer_size(默認值:8388608即:8M)、query_cache_size(默認值:33554432即:32M)等五個。總共:560M. 這些變量值均可以經過命令如:show variables like '變量名';查看到。
|
4.2.1.1:key_buffer_size,本系統目前爲384M,可修改成400M
key_buffer_size=400M
key_buffer_size是用於索引塊的緩衝區大小,增長它可獲得更好處理的索引(對全部讀和多重寫),對MyISAM(MySQL表存儲的一種類型,能夠百度等查看詳情)表性能影響最大的一個參數。若是你使它太大,系統將開始換頁而且真的變慢了。嚴格說是它決定了數據庫索引處理的速度,尤爲是索引讀的速度。對於內存在4GB左右的服務器該參數可設置爲256M或384M. 怎麼才能知道key_buffer_size的設置是否合理呢,通常能夠檢查狀態值Key_read_requests和Key_reads ,比例key_reads / key_read_requests應該儘量的低,好比1:100,1:1000 ,1:10000。其值能夠用如下命令查得:show status like 'key_read%'; 好比查看系統當前key_read和key_read_request值爲: +-------------------+-------+ | Variable_name | Value | +-------------------+-------+ | Key_read_requests | 28535 | | Key_reads | 269 | +-------------------+-------+ 可知道有28535個請求,有269個請求在內存中沒有找到直接從硬盤讀取索引. 未命中緩存的機率爲:0.94%=269/28535*100%. 通常未命中機率在0.1之下比較好。目前已遠遠大於0.1,證實效果很差。若命中率在0.01如下,則建議適當的修改key_buffer_size值。 http://dbahacker.com/mysql/innodb-myisam-compare(InnoDB與MyISAM的六大區別) http://kb.cnblogs.com/page/99810/(查看存儲引擎介紹) MyISAM、InnoDB、MyISAM Merge引擎、InnoDB、memory(heap)、archive |
4.2.1.2:innodb_buffer_pool_size(默認128M)
innodb_buffer_pool_size=1024M(1G)
innodb_buffer_pool_size:主要針對InnoDB表性能影響最大的一個參數。功能與Key_buffer_size同樣。InnoDB佔用的內存,除innodb_buffer_pool_size用於存儲頁面緩存數據外,另外正常狀況下還有大約8%的開銷,主要用在每一個緩存頁幀的描述、adaptive hash等數據結構,若是不是安全關閉,啓動時還要恢復的話,還要另開大約12%的內存用於恢復,二者相加就有差很少21%的開銷。假設:12G的innodb_buffer_pool_size,最多的時候InnoDB就可能佔用到14.5G的內存。若系統只有16G,並且只運行MySQL,且MySQL只用InnoDB, 那麼爲MySQL開12G,是最大限度地利用內存了。 另外InnoDB和 MyISAM 存儲引擎不一樣, MyISAM 的 key_buffer_size 只能緩存索引鍵,而 innodb_buffer_pool_size 卻能夠緩存數據塊和索引鍵。適當的增長這個參數的大小,能夠有效的減小 InnoDB 類型的表的磁盤 I/O 。 當咱們操做一個 InnoDB 表的時候,返回的全部數據或者去數據過程當中用到的任何一個索引塊,都會在這個內存區域中走一遭。 能夠經過 (Innodb_buffer_pool_read_requests – Innodb_buffer_pool_reads) / Innodb_buffer_pool_read_requests * 100% 計算緩存命中率,並根據命中率來調整 innodb_buffer_pool_size 參數大小進行優化。值能夠用如下命令查得:show status like 'Innodb_buffer_pool_read%'; 好比查看當前系統中系統中 | Innodb_buffer_pool_read_requests | 1283826 | | Innodb_buffer_pool_reads | 519 | +---------------------------------------+---------+ 其命中率99.959%=(1283826-519)/1283826*100% 命中率越高越好。 |
4.2.1.3:innodb_additional_mem_pool_size(默認8M)
innodb_additional_mem_pool_size=20M
innodb_additional_mem_pool_size 設置了InnoDB存儲引擎用來存放數據字典信息以及一些內部數據結構的內存空間大小,因此當咱們一個MySQL Instance中的數據庫對象很是多的時候,是須要適當調整該參數的大小以確保全部數據都能存放在內存中提升訪問效率的。 這個參數大小是否足夠仍是比較容易知道的,由於當太小的時候,MySQL會記錄Warning信息到數據庫的error log中,這時候你就知道該調整這個參數大小了。 查看當前系統mysql的error日誌 cat /var/lib/mysql/機器名.error 發現有不少waring警告。因此要調大爲20M. 根據MySQL手冊,對於2G內存的機器,推薦值是20M。 32G內存的 100M |
4.2.1.4:innodb_log_buffer_size(默認8M)
innodb_log_buffer_size=20M
innodb_log_buffer_size 這是InnoDB存儲引擎的事務日誌所使用的緩衝區。相似於Binlog Buffer,InnoDB在寫事務日誌的時候,爲了提升性能,也是先將信息寫入Innofb Log Buffer中,當知足innodb_flush_log_trx_commit參數所設置的相應條件(或者日誌緩衝區寫滿)以後,纔會將日誌寫到文件 (或者同步到磁盤)中。能夠經過innodb_log_buffer_size 參數設置其可使用的最大內存空間。 InnoDB 將日誌寫入日誌磁盤文件前的緩衝大小。理想值爲 1M 至 8M。大的日誌緩衝容許事務運行時不須要將日誌保存入磁盤而只到事務被提交(commit)。 所以,若是有大的事務處理,設置大的日誌緩衝能夠減小磁盤I/O。 在 my.cnf中以數字格式設置。 默認是8MB,系的如頻繁的系統可適當增大至4MB~8MB。固然如上面介紹所說,這個參數實際上還和另外的flush參數相關。通常來講不建議超過32MB 注:innodb_flush_log_trx_commit參數對InnoDB Log的寫入性能有很是關鍵的影響,默認值爲1。該參數能夠設置爲0,1,2,解釋以下: 0:log buffer中的數據將以每秒一次的頻率寫入到log file中,且同時會進行文件系統到磁盤的同步操做,可是每一個事務的commit並不會觸發任何log buffer 到log file的刷新或者文件系統到磁盤的刷新操做; 1:在每次事務提交的時候將log buffer 中的數據都會寫入到log file,同時也會觸發文件系統到磁盤的同步; 2:事務提交會觸發log buffer到log file的刷新,但並不會觸發磁盤文件系統到磁盤的同步。此外,每秒會有一次文件系統到磁盤同步操做。 實際測試發現,該值對插入數據的速度影響很是大,設置爲2時插入10000條記錄只須要2秒,設置爲0時只須要1秒,而設置爲1時則須要229秒。所以,MySQL手冊也建議儘可能將插入操做合併成一個事務,這樣能夠大幅提升速度。根據MySQL手冊,在存在丟失最近部分事務的危險的前提下,能夠把該值設爲0。 |
4.5.1.5:query_cache_size(默認32M)
query_cache_size=40M
query_cache_size: 主要用來緩存MySQL中的ResultSet,也就是一條SQL語句執行的結果集,因此僅僅只能針對select語句。當咱們打開了 Query Cache功能,MySQL在接受到一條select語句的請求後,若是該語句知足Query Cache的要求(未顯式說明不容許使用Query Cache,或者已經顯式申明須要使用Query Cache),MySQL會直接根據預先設定好的HASH算法將接受到的select語句以字符串方式進行hash,而後到Query Cache中直接查找是否已經緩存。也就是說,若是已經在緩存中,該select請求就會直接將數據返回,從而省略了後面全部的步驟(如SQL語句的解析,優化器優化以及向存儲引擎請求數據等),極大的提升性能。根據MySQL用戶手冊,使用查詢緩衝最多能夠達到238%的效率。 固然,Query Cache也有一個致命的缺陷,那就是當某個表的數據有任何任何變化,都會致使全部引用了該表的select語句在Query Cache中的緩存數據失效。因此,當咱們的數據變化很是頻繁的狀況下,使用Query Cache可能會得不償失 Query Cache的使用須要多個參數配合,其中最爲關鍵的是query_cache_size和query_cache_type,前者設置用於緩存 ResultSet的內存大小,後者設置在何場景下使用Query Cache。在以往的經驗來看,若是不是用來緩存基本不變的數據的MySQL數據庫,query_cache_size通常256MB是一個比較合適的大小。固然,這能夠經過計算Query Cache的命中率(Qcache_hits/(Qcache_hits+Qcache_inserts)*100))來進行調整。 query_cache_type能夠設置爲0(OFF),1(ON)或者2(DEMOND),分別表示徹底不使用query cache,除顯式要求不使用query cache(使用sql_no_cache)以外的全部的select都使用query cache,只有顯示要求才使用query cache(使用sql_cache)。若是Qcache_lowmem_prunes的值很是大,則代表常常出現緩衝. 若是Qcache_hits的值也很是大,則代表查詢緩衝使用很是頻繁,此時須要增長緩衝大小; 根據命中率(Qcache_hits/(Qcache_hits+Qcache_inserts)*100))進行調整,通常不建議太大,256MB可能已經差很少了,大型的配置型靜態數據可適當調大. 能夠經過命令:show status like 'Qcache_%';查看目前系統Query catch使用大小 | Qcache_hits | 1892463 | | Qcache_inserts | 35627 命中率98.17%=1892463/(1892463 +35627 )*100 |
除了全局緩衝,MySql還會爲每一個鏈接發放鏈接緩衝。個鏈接到MySQL服務器的線程都須要有本身的緩衝。大概須要馬上分配256K,甚至在線程空閒時,它們使用默認的線程堆棧,網絡緩存等。事務開始以後,則須要增長更多的空間。運行較小的查詢可能僅給指定的線程增長少許的內存消耗,然而若是對數據表作複雜的操做例如掃描、排序或者須要臨時表,則需分配大約read_buffer_size, sort_buffer_size,read_rnd_buffer_size,tmp_table_size 大小的內存空間. 不過它們只是在須要的時候才分配,而且在那些操做作完以後就釋放了。有的是馬上分配成單獨的組塊。tmp_table_size 可能高達MySQL所能分配給這個操做的最大內存空間了 。注意,這裏須要考慮的不僅有一點——可能會分配多個同一種類型的緩存,例如用來處理子查詢。一些特殊的查詢的內存使用量可能更大——若是在MyISAM表上作成批的插入 時須要分配 bulk_insert_buffer_size 大小的內存;執行 ALTER TABLE, OPTIMIZE TABLE, REPAIR TABLE 命令時須要分配 myisam_sort_buffer_size 大小的內存。 |
4.2.2.1:read_buffer_size(默認值:2097144即2M)
read_buffer_size=4M
read_buffer_size 是MySql讀入緩衝區大小。對錶進行順序掃描的請求將分配一個讀入緩衝區,MySql會爲它分配一段內存緩衝區。read_buffer_size變量控制這一 緩衝區的大小。若是對錶的順序掃描請求很是頻繁,而且你認爲頻繁掃描進行得太慢,能夠經過增長該變量值以及內存緩衝區大小提升其性能. |
4.2.2.2:sort_buffer_size(默認值:2097144即2M)
sort_buffer_size=4M
sort_buffer_size是MySql執行排序使用的緩衝大小。若是想要增長ORDER BY的速度,首先看是否可讓MySQL使用索引而不是額外的排序階段。若是不能,能夠嘗試增長sort_buffer_size變量的大小 |
4.2.2.3: read_rnd_buffer_size(默認值:8388608即8M)
read_rnd_buffer_size=8M
read_rnd_buffer_size 是MySql的隨機讀緩衝區大小。當按任意順序讀取行時(例如,按照排序順序),將分配一個隨機讀緩存區。進行排序查詢時,MySql會首先掃描一遍該緩衝,以免磁盤搜索,提升查詢速度,若是須要排序大量數據,可適當調高該值。但MySql會爲每一個客戶鏈接發放該緩衝空間,因此應儘可能適當設置該值,以免內存開 銷過大。 |
4.2.2.4: tmp_table_size(默認值:8388608 即:16M)
tmp_table_size=16M
tmp_table_size是MySql的heap (堆積)表緩衝大小。全部聯合在一個DML指令內完成,而且大多數聯合甚至能夠不用臨時表便可以完成。大多數臨時表是基於內 存的(HEAP)表。具備大的記錄長度的臨時表 (全部列的長度的和)或包含BLOB列的表存儲在硬盤上。若是某個內部heap(堆積)表大小超過tmp_table_size,MySQL能夠根據須要自 動將內存中的heap表改成基於硬盤的MyISAM表。還能夠經過設置tmp_table_size選項來增長臨時表的大小。也就是說,若是調高該值,MySql同時將增長heap表的大小,可達到提升 聯接查詢速度的效果。 |
4.2.2.5:record_buffer:(默認值:)
record_buffer每一個進行一個順序掃描的線程爲其掃描的每張表分配這個大小的一個緩衝區。若是你作不少順序掃描,你可能想要增長該值。默認數值是131072 (128K) |
4.2.3.1:table_cache(默認值:512)
TABLE_CACHE(5.1.3及之後版本又名TABLE_OPEN_CACHE) table_cache指定表高速緩存的大小。每當MySQL訪問一個表時,若是在表緩衝區中還有空間,該表就被打開並放入其中,這樣能夠更快地訪問表內容。經過檢查峯值時間的狀態值Open_tables和Opened_tables,能夠決定是否須要增長table_cache的值。若是你發現open_tables等於table_cache,而且opened_tables在不斷增加,那麼你就須要增長table_cache的值了(上述狀態值可使用SHOW STATUS LIKE ‘Open%tables’得到)。注意,不能盲目地把table_cache設置成很大的值。若是設置得過高,可能會形成文件描述符不足,從而形成性能不穩定或者鏈接失敗。 SHOW STATUS LIKE 'Open%tables'; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | Open_tables | 356 | | Opened_tables | 0 | +---------------+-------+ 2 rows in set (0.00 sec) open_tables表示當前打開的表緩存數,若是執行flush tables操做,則此係統會關閉一些當前沒有使用的表緩存而使得此狀態值減少; opend_tables表示曾經打開的表緩存數,會一直進行累加,若是執行flush tables操做,值不會減少。 在mysql默認安裝狀況下,table_cache的值在2G內存如下的機器中的值默認時256到512,若是機器有4G內存,則默認這個值 是2048,但這決意味着機器內存越大,這個值應該越大,由於table_cache加大後,使得mysql對SQL響應的速度更快了,不可避免的會產生 更多的死鎖(dead lock),這樣反而使得數據庫整個一套操做慢了下來,嚴重影響性能。因此平時維護中仍是要根據庫的實際狀況去做出判斷,找到最適合你維護的庫的 table_cache值。 因爲MySQL是多線程的機制,爲了提升性能,每一個線程都是獨自打開本身須要的表的文件描 述符,而不是經過共享已經打開的.針對不一樣存儲引擎處理的方法固然也不同 在myisam表引擎中,數據文件的描述符 (descriptor)是不共享的,可是索引文件的描述符倒是全部線程共享的.Innodb中和使用表空間類型有關,假如是共享表空間那麼實際就一個數 據文件,固然佔用的數據文件描述符就會比獨立表空間少.
這個數據遭到不少質疑,table_cache夠用就好,檢查 Opened_tables值,若是這個值很大,或增加很快那麼你就得考慮加大table_cache了. table_cache:全部線程打開的表的數目。增大該值能夠增長mysqld須要的文件描述符的數量。默認值是64. |
4.2.3.2 thread_cache_size (服務器線程緩存)
thread_cache_size=64
默認的thread_cache_size=8,可是看到好多配置的樣例裏的值通常是32,64,甚至是128,感受這個參數對優化應該有幫助,因而查了下: mysql> show status like 'thread%'; 查看開機起來數據庫被鏈接了多少次? mysql> show status like '%connection%'; 經過鏈接線程池的命中率來判斷設置值是否合適?命中率超過90%以上,設定合理。 (Connections - Threads_created) / Connections * 100 % |