實時監控當前操做系統的負載狀況的,每秒刷新一次狀態,一般會關注三大指標(CPU、MEM、IO)mysql
load average: 0.00, 0.00, 0.00:總體的負載狀況,判斷標準,若是值很是高,只能告訴咱們操做系統很繁忙 CPU使用狀況:Cpu(s): 0.2%us, 0.2%sy, 99.7%id, 0.0%wa %id: CPU空閒的百分比 %us:用戶程序,佔用的CPU時間片的百分比。咱們認爲us%高是好事,但要在cpu正常能力範圍內。 %sy:系統程序(和內核工做有關),資源調配,資源管理,內核其餘功能的管理(system call)對於比較成熟的操做系統,對sy%應該是佔比不多的。咱們認爲越少越好。若是飆升,可能說明兩件事情,1,系統bug;2,中病毒了 %wa 這個參數越少越好。若是wait高說明了,1,IO很慢(速度慢,全表掃描)二、內存滿了OOM(內存小,全表掃描) Mem:內存使用狀況 total:總的內存量 used:已經被使用的內存量 free:空閒的內存空間 buffer:專門負責操做系統當中,與文件修改類操做有關的內存緩衝區(專門負責寫操做的),能夠被重複利用的內存區域 cached:專門負責操做系統當中,與文件讀取有關的緩存區域(專門負責文件讀取操做的),對於操做系統可用內存量=free+buffer+cached used:used=RSS+anon+buffer+cached linux系統內存劃分的三個區域 RSS:常駐內存集,主要負責程序運行須要的內存區域 Page Cache:文件系統緩存,主要負責文件有關的緩衝和緩存,buffer+cached anon page: 匿名頁,主要負責程序之間交互時使用到內存區域 經過如下命令,手工釋放全部buffer和cached echo 3 > /proc/sys/vm/drop_caches SWAP:交換分區,當內存緊張的時候,會將內存區域當中的數據臨時置換到SWAP中。 默認:在內存使用量達到60% [root@db02 ~]# cat /proc/sys/vm/swappiness 60 對於MySQL環境,要儘可能避免swap使用 sysctl.conf 臨時修改: [root@db02 ~]# echo 0 >/proc/sys/vm/swappiness
測試當前環境IO水平
mount /dev/sdb /data
iostat -dm 1 /dev/sdb
dd if=/dev/zero of=/data/bigfilelinux
在優化過程當中,咱們通常會結合CPU和內存的使用狀況看IO狀態 CPU很是繁忙(MYSQL): 一、user 很高 再看IO水平,正常狀況下IO也會很高 不正常的狀況,user很高,可是IO很低? 在作大量的計算(多表鏈接查詢、排序、分組、子查詢很複雜或者很頻繁) 二、wait 很高 IO不多 (1)頗有多是全表掃描 (2)IO有問題(RAID規劃或者磁盤IO自己問題)
[root@db03 ~]# vmstat 1 10 procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu----- r b swpd free buff cache si so bi bo in cs us sy id wa st 2 0 28348 122752 0 349308 0 0 60 100 102 101 4 1 94 0 0 0 0 28348 122752 0 349308 0 0 0 0 38 82 0 1 99 0 0 0 0 28348 122752 0 349308 0 0 0 0 43 91 0 0 100 0 0 0 0 28348 122752 0 349308 0 0 0 0 37 78 0 0 100 0 0
須要手動安裝:yum -y install dstatios
[root@db03 ~]# dstat You did not select any stats, using -cdngy by default. ----total-cpu-usage---- -dsk/total- -net/total- ---paging-- ---system-- usr sys idl wai hiq siq| read writ| recv send| in out | int csw 4 1 94 0 0 0| 59k 100k| 0 0 | 50B 512B| 101 100 0 1 99 0 0 0| 0 0 | 60B 890B| 0 0 | 62 127 0 0 100 0 0 0| 0 0 | 60B 346B| 0 0 | 53 113 0 6 94 0 0 0| 0 14M| 60B 346B| 0 0 | 262 132 0 0 100 0 0 0| 0 0 | 60B 346B| 0 0 | 52 117 0 1 99 0 0 0| 0 0 | 60B 346B| 0 0 | 60 121 0 0 100 0 0 0| 0 0 | 60B 346B| 0 0 | 60 131 0 0 100 0 0 0| 0 0 | 60B 346B| 0 0 | 68 134 0 0 100 0 0 0| 0 0 | 60B 346B| 0 0 | 51 117 0 1 99 0 0 0| 0 0 | 60B 346B| 0 0 | 57 108 0 0 100 0 0 0| 0 0 | 60B 346B| 0 0 | 51 112 ^C
基礎優化命令工具 (1)mysql 用法舉例: mysql -uroot -p123 -e "show status like '%lock%'" (2)SHOW ENGINE INNODB STATUS mysql> show engine innodb status\G 通常關注比較多的: 內存、鎖相關 (3)show index:查看索引 mysql> show index from proc; (4)Information_Schema:系通通計表 mysql>use Information_Schema mysql> select * from INNODB_SYS_TABLES; (5)mysql庫下的 innodb_table_stats innodb_index_stats mysql> use msyql ERROR 1049 (42000): Unknown database 'msyql' mysql> use mysql mysql> select * from innodb_table_stats; (6) SHOW [SESSION | GLOBAL] STATUS:查看全局會話狀誠 (7) SHOW [FULL] PROCESSLIST(應急調優) (8) explain (9) mysqldumpslow (pt-query-diagest):分析慢日誌 深度優化命令工具(擴展) mysqlslap:壓力測試工具 sysbench:壓力測試工具 tpcc:壓力測試工具 Performance Schema(5.7默認開啓)
主機: 根據數據庫類型 (1)主機CPU選擇 IO密集型:能夠處理多併發的CPU類型,特色是核心數量較多,主頻中等 Intel E系列 CPU密集型:能夠處理高性能計算的cpu類型,主頻很是高,核心數量中等 Intel I系列的 MySQL的線上業務,處理高併發訪問的業務。屬於IO密集型的業務,因此選擇志強系列的CPU更好一些。 MySQL非線上的業務,數據處理數據分析,屬於CPU密集型業務,因此選擇I系列的CPU。 (2)內存容量選擇 通常是選擇cpu核心數量的2倍 (3)IO的選擇 一、磁盤選擇 SATAIII SAS FC SSD pci-e SSD Flash 主機 RAID卡的BBU(Battery Backup Unit)關閉 存儲(有條件的公司會選擇單獨存儲設備): 根據存儲數據種類的不一樣,選擇不一樣的存儲設備 配置合理的RAID級別(raid五、raid十、熱備盤) raid0 :性能高(條帶化),安全性和單盤同樣 raid1 :安全性高(條帶化功能),性能和單盤同樣 raid10 :讀寫性能都很高(0級別條帶化功能),安全性高(1級別,鏡像功能),企業若是有條件推薦的一種raid級別 raid5 :較好的安全性(校驗),較好的性能(條帶化功能,讀性能比較高,寫性能通常),對於讀多寫少的業務可使用此級別 高端存儲:IBM EMC HDS,通常都是raid1(就是raid10) ,自帶條帶化功能,並且只支持4塊盤作一個raid 使用合適raid級別,避免過分條帶化 IOPS峯值:對於每一塊硬件磁盤來說,都有一個固定參數IOPS,每秒最多可以進行的IO的次數。 網絡設備: 使用流量支持更高的網絡設備(交換機、路由器、網線、網卡、HBA卡) 網卡綁定: bonding 0(負載,負載的提早是交換機要作堆疊) 1(主備)
一、Swap調整 /proc/sys/vm/swappiness的內容改爲0(臨時) echo 0>/proc/sys/vm/swappiness /etc/sysctl.conf上添加vm.swappiness=0(永久) vim /etc/sysctl.conf vm.swappiness=0 sysctl -p 這個參數決定了Linux是傾向於使用swap,仍是傾向於釋放文件系統cache。在內存緊張的狀況下,數值越低越傾向於釋放文件系統cache。 固然,這個參數只能減小使用swap的機率,並不能避免Linux使用swap。 二、IO調度策略 臨時修改: [root@db02 ~]# cat /sys/block/sda/queue/scheduler noop anticipatory deadline [cfq] [root@db02 ~]# echo deadline >/sys/block/sda/queue/scheduler [root@db02 ~]# cat /sys/block/sda/queue/scheduler noop anticipatory [deadline] cfq 永久修改: 更改到以下內容: vim /etc/default/grub,添加elevator=deadline GRUB_CMDLINE_LINUX="rd.lvm.lv=centos/root rd.lvm.lv=centos/swap biosdevname=0 net.ifnames=0 elevator=deadline rhgb quiet" [root@db03 grub]# vim /boot/grub2/grub.cfg 三、關閉無用服務 chkconfig --level 23456 acpid off chkconfig --level 23456 anacron off chkconfig --level 23456 autofs off chkconfig --level 23456 avahi-daemon off chkconfig --level 23456 bluetooth off chkconfig --level 23456 cups off chkconfig --level 23456 firstboot off chkconfig --level 23456 haldaemon off chkconfig --level 23456 hplip off chkconfig --level 23456 ip6tables off chkconfig --level 23456 iptables off chkconfig --level 23456 isdn off chkconfig --level 23456 pcscd off chkconfig --level 23456 sendmail off chkconfig --level 23456 yum-updatesd off 以上:硬件優化建議,操做系統優化建議,應該在業務架構搭建初始應該作好。
MySQL參數優化測試建議 1、參數優化前壓力測試 0、優化測試前提 MacBook:虛擬機vm12.5,OS centos 6.9(系統已優化),cpu*2(I5 4288u 2.6GHZ),MEM*4GB ,HardDisk:Apple SSD(SM-0512F) 一、模擬數據庫數據 爲了測試咱們建立一個test1的庫建立一個tb1的表,而後導入20萬行數據,腳本以下: vim slap.sh #!/bin/bash HOSTNAME="localhost" PORT="3306" USERNAME="root" PASSWORD="123" DBNAME="oldboy" TABLENAME="lufei" #create database mysql -h ${HOSTNAME} -P${PORT} -u${USERNAME} -p${PASSWORD} -e "drop database if exists ${DBNAME}" create_db_sql="create database if not exists ${DBNAME}" mysql -h ${HOSTNAME} -P${PORT} -u${USERNAME} -p${PASSWORD} -e "${create_db_sql}" #create table create_table_sql="create table if not exists ${TABLENAME}(stuid int not null primary key,stuname varchar(20) not null,stusex char(1) not null,cardid varchar(20) not null,birthday datetime,entertime datetime,address varchar(100) default null)" mysql -h ${HOSTNAME} -P${PORT} -u${USERNAME} -p${PASSWORD} ${DBNAME} -e "${create_table_sql}" #insert data to table i="1" while [ $i -le 200000 ] do insert_sql="insert into ${TABLENAME} values($i,''guojialei_$i,'1','110011198809163418','1988-09-16','2017-09-13','oldboyedu_$i')" mysql -h ${HOSTNAME} -P${PORT} -u${USERNAME} -p${PASSWORD} ${DBNAME} -e "${insert_sql}" let i++ done #select data select_sql="select count(*) from ${TABLENAME}" mysql -h ${HOSTNAME} -P${PORT} -u${USERNAME} -p${PASSWORD} ${DBNAME} -e "${select_sql}" 執行腳本: sh slap.sh 二、檢查數據可用性 mysql -uroot -p123 select count(*) from test1.tb1; 三、在沒有優化以前咱們使用mysqlslap來進行壓力測試 mysqlslap --defaults-file=/etc/my.cnf \ --concurrency=100 --iterations=1 --create-schema='test1' \ --query='select * from test1.tb1' engine=innodb \ --number-of-queries=2000 -uroot -p123 -verbose Benchmark Running for engine rbose Average number of seconds to run all queries: 31.463 seconds Minimum number of seconds to run all queries: 31.463 seconds Maximum number of seconds to run all queries: 31.463 seconds Number of clients running queries: 100 Average number of queries per client: 20 --------------------------------mysqlslap使用說明---------------------------- mysqlslap工具介紹 mysqlslap來自於mariadb包,測試的過程默認生成一個mysqlslap的schema,生成測試表t1,查詢和插入測試數據,mysqlslap庫自動生成,若是已經存在則先刪除。用--only-print來打印實際的測試過程,整個測試完成後不會在數據庫中留下痕跡。 經常使用選項: --auto-generate-sql, -a 自動生成測試表和數據,表示用mysqlslap工具本身生成的SQL腳原本測試併發壓力 --auto-generate-sql-load-type=type 測試語句的類型。表明要測試的環境是讀操做仍是寫操做仍是二者混合的。取值包括:read,key,write,update和mixed(默認) --auto-generate-sql-add-auto-increment 表明對生成的表自動添加auto_increment列,從5.1.18版本開始支持 --number-char-cols=N, -x N 自動生成的測試表中包含多少個字符類型的列,默認1 --number-int-cols=N, -y N 自動生成的測試表中包含多少個數字類型的列,默認1 --number-of-queries=N 總的測試查詢次數(併發客戶數×每客戶查詢次數) --query=name,-q 使用自定義腳本執行測試,例如能夠調用自定義的存儲過程或者sql語句來執行測試 --create-schema 表明自定義的測試庫名稱,測試的schema,MySQL中schema也就是database --commint=N 多少條DML後提交一次 --compress, -C 如服務器和客戶端都支持壓縮,則壓縮信息 --concurrency=N, -c N 表示併發量,即模擬多少個客戶端同時執行select;可指定多個值,以逗號或者--delimiter參數指定值作爲分隔符 --engine=engine_name, -e engine_name 表明要測試的引擎,能夠有多個,用分隔符隔開 --iterations=N, -i N 測試執行的迭代次數,表明要在不一樣併發環境下,各自運行測試多少次 --only-print 只打印測試語句而不實際執行 --detach=N 執行N條語句後斷開重連 --debug-info, -T 打印內存和CPU的相關信息 測試示例: 1)單線程測試 [root@centos7 ~]# mysqlslap -a -uroot -p Enter password: Benchmark Average number of seconds to run all queries: 0.004 seconds Minimum number of seconds to run all queries: 0.004 seconds Maximum number of seconds to run all queries: 0.004 seconds Number of clients running queries: 1 Average number of queries per client: 0 2)多線程測試,使用--concurrency來模擬併發鏈接 [root@centos7 ~]# mysqlslap -uroot -p -a -c 500 Enter password: Benchmark Average number of seconds to run all queries: 3.384 seconds Minimum number of seconds to run all queries: 3.384 seconds Maximum number of seconds to run all queries: 3.384 seconds Number of clients running queries: 500 Average number of queries per client: 0 3)同時測試不一樣的存儲引擎的性能進行對比 [root@centos7 ~]# mysqlslap -uroot -p -a --concurrency=500 --number-of-queries 1000 --iterations=5 --engine=myisam,innodb --debug-info Enter password: Benchmark Running for engine myisam Average number of seconds to run all queries: 0.192 seconds Minimum number of seconds to run all queries: 0.187 seconds Maximum number of seconds to run all queries: 0.202 seconds Number of clients running queries: 500 Average number of queries per client: 2 Benchmark Running for engine innodb Average number of seconds to run all queries: 0.355 seconds Minimum number of seconds to run all queries: 0.350 seconds Maximum number of seconds to run all queries: 0.364 seconds Number of clients running queries: 500 Average number of queries per client: 2 User time 0.33, System time 0.58 Maximum resident set size 22892, Integral resident set size 0 Non-physical pagefaults 46012, Physical pagefaults 0, Swaps 0 Blocks in 0 out 0, Messages in 0 out 0, Signals 0 Voluntary context switches 31896, Involuntary context switches 0 4)執行一次測試,分別500和1000個併發,執行5000次總查詢 [root@centos7 ~]# mysqlslap -uroot -p -a --concurrency=500,1000 --number-of-queries 5000 --debug-info Enter password: Benchmark Average number of seconds to run all queries: 3.378 seconds Minimum number of seconds to run all queries: 3.378 seconds Maximum number of seconds to run all queries: 3.378 seconds Number of clients running queries: 500 Average number of queries per client: 10 Benchmark Average number of seconds to run all queries: 3.101 seconds Minimum number of seconds to run all queries: 3.101 seconds Maximum number of seconds to run all queries: 3.101 seconds Number of clients running queries: 1000 Average number of queries per client: 5 User time 0.84, System time 0.64 Maximum resident set size 83068, Integral resident set size 0 Non-physical pagefaults 139977, Physical pagefaults 0, Swaps 0 Blocks in 0 out 0, Messages in 0 out 0, Signals 0 Voluntary context switches 31524, Involuntary context switches 3 5)迭代測試 [root@centos7 ~]# mysqlslap -uroot -p -a --concurrency=500 --number-of-queries 5000 --iterations=5 --debug-info Enter password: Benchmark Average number of seconds to run all queries: 3.307 seconds Minimum number of seconds to run all queries: 3.184 seconds Maximum number of seconds to run all queries: 3.421 seconds Number of clients running queries: 500 Average number of queries per client: 10 User time 2.18, System time 1.58 Maximum resident set size 74872, Integral resident set size 0 Non-physical pagefaults 327732, Physical pagefaults 0, Swaps 0 Blocks in 0 out 0, Messages in 0 out 0, Signals 0 Voluntary context switches 73904, Involuntary context switches 3 ---------------------------------------------------------------------------- 2、優化細節: 一、參數優化 1.1 Max_connections (1)簡介 Mysql的最大鏈接數,若是服務器的併發請求量比較大,能夠調高這個值,固然這是要創建在機器可以支撐的狀況下,由於若是鏈接數愈來愈多,mysql會爲每一個鏈接提供緩衝區,就會開銷的越多的內存,因此須要適當的調整該值,不能隨便去提升設值。 (2)判斷依據 show variables like 'max_connections'; +-----------------+-------+ | Variable_name | Value | +-----------------+-------+ | max_connections | 151 | +-----------------+-------+ show status like 'Max_used_connections'; +----------------------+-------+ | Variable_name | Value | +----------------------+-------+ | Max_used_connections | 101 | +----------------------+-------+ 若是max_used_connections跟max_connections相同,那麼就是max_connections設置太低或者超過服務器的負載上限了,低於10%則設置過大. (3)修改方式舉例 vim /etc/my.cnf Max_connections=1024 1.2 back_log (1)簡介 mysql能暫存的鏈接數量,當主要mysql線程在一個很短期內獲得很是多的鏈接請求時候它就會起做用,若是mysql的鏈接數據達到max_connections時候,新來的請求將會被存在堆棧中,等待某一鏈接釋放資源,該推棧的數量及back_log,若是等待鏈接的數量超過back_log,將不被授予鏈接資源。 back_log值指出在mysql暫時中止回答新請求以前的短期內有多少個請求能夠被存在推棧中,只有若是指望在一個短期內有不少鏈接的時候須要增長它 (2)判斷依據 show full processlist 發現大量的待鏈接進程時,就須要加大back_log或者加大max_connections的值 (3)修改方式舉例 vim /etc/my.cnf back_log=1024 1.3 wait_timeout和interactive_timeout (1)簡介 wait_timeout:指的是mysql在關閉一個非交互的鏈接以前所要等待的秒數 interactive_timeout:指的是mysql在關閉一個交互的鏈接以前所須要等待的秒數,好比咱們在終端上進行mysql管理,使用的即便交互的鏈接,這時候,若是沒有操做的時間超過了interactive_time設置的時間就會自動的斷開,默認的是28800,可調優爲7200。 wait_timeout:若是設置過小,那麼鏈接關閉的就很快,從而使一些持久的鏈接不起做用 (2)設置建議 若是設置太大,容易形成鏈接打開時間過長,在show processlist時候,能看到不少的鏈接 ,通常但願wait_timeout儘量低 (3)修改方式舉例 wait_timeout=1200 interactive_timeout=1200 1.4 key_buffer_size (1)簡介 key_buffer_size指定索引緩衝區的大小,它決定索引處理的速度,尤爲是索引讀的速度 (2)設置依據 經過key_read_requests和key_reads能夠直到key_baffer_size設置是否合理。 mysql> show variables like "key_buffer_size%"; +-----------------+---------+ | Variable_name | Value | +-----------------+---------+ | key_buffer_size | 8388608 | +-----------------+---------+ 1 row in set (0.00 sec) mysql> mysql> show status like "key_read%"; +-------------------+-------+ | Variable_name | Value | +-------------------+-------+ | Key_read_requests | 10 | | Key_reads | 2 | +-------------------+-------+ 2 rows in set (0.00 sec) mysql> 一共有10個索引讀取請求,有2個請求在內存中沒有找到直接從硬盤中讀取索引 ----------------------------------------------------- 注:key_buffer_size只對myisam表起做用,即便不使用myisam表,可是內部的臨時磁盤表是myisam表,也要使用該值。 可使用檢查狀態值created_tmp_disk_tables得知: mysql> show status like "created_tmp%"; +-------------------------+-------+ | Variable_name | Value | +-------------------------+-------+ | Created_tmp_disk_tables | 0 | | Created_tmp_files | 6 | | Created_tmp_tables | 1 | +-------------------------+-------+ 3 rows in set (0.00 sec) mysql> 一般地,咱們習慣以 Created_tmp_tables/(Created_tmp_disk_tables + Created_tmp_tables) 或者已各自的一個時段內的差額計算,來判斷基於內存的臨時表利用率。因此,咱們會比較關注 Created_tmp_disk_tables 是否過多,從而認定當前服務器運行情況的優劣。 看如下例子: 在調用mysqldump備份數據時,大概執行步驟以下: 180322 17:39:33 7 Connect root@localhost on 7 Query /*!40100 SET @@SQL_MODE='' */ 7 Init DB guo 7 Query SHOW TABLES LIKE 'guo' 7 Query LOCK TABLES `guo` READ /*!32311 LOCAL */ 7 Query SET OPTION SQL_QUOTE_SHOW_CREATE=1 7 Query show create table `guo` 7 Query show fields from `guo` 7 Query show table status like 'guo' 7 Query SELECT /*!40001 SQL_NO_CACHE */ * FROM `guo` 7 Query UNLOCK TABLES 7 Quit 其中,有一步是:show fields from `guo`。從slow query記錄的執行計劃中,能夠知道它也產生了 Tmp_table_on_disk。 因此說,以上公式並不能真正反映到mysql裏臨時表的利用率,有些狀況下產生的 Tmp_table_on_disk 咱們徹底不用擔憂,所以不必過度關注 Created_tmp_disk_tables,但若是它的值大的離譜的話,那就好好查一下,你的服務器到底都在執行什麼查詢了。 -------------------------------------------- (3)配置方法 key_buffer_size=64M 1.5 query_cache_size (1)簡介: 查詢緩存簡稱QC,使用查詢緩衝,mysql將查詢結果存放在緩衝區中,從此對於一樣的select語句(區分大小寫),將直接從緩衝區中讀取結果。 一個sql查詢若是以select開頭,那麼mysql服務器將嘗試對其使用查詢緩存。 注:兩個sql語句,只要想差哪怕是一個字符(列如大小寫不同;多一個空格等),那麼這兩個sql將使用不一樣的一個cache。 (2)判斷依據 mysql> show status like "%Qcache%"; +-------------------------+---------+ | Variable_name | Value | +-------------------------+---------+ | Qcache_free_blocks | 1 | | Qcache_free_memory | 1031360 | | Qcache_hits | 0 | | Qcache_inserts | 0 | | Qcache_lowmem_prunes | 0 | | Qcache_not_cached | 2002 | | Qcache_queries_in_cache | 0 | | Qcache_total_blocks | 1 | +-------------------------+---------+ 8 rows in set (0.00 sec) ---------------------狀態說明-------------------- Qcache_free_blocks:緩存中相鄰內存塊的個數。若是該值顯示較大,則說明Query Cache 中的內存碎片較多了,FLUSH QUERY CACHE會對緩存中的碎片進行整理,從而獲得一個空閒塊。 注:當一個表被更新以後,和它相關的cache blocks將被free。可是這個block依然可能存在隊列中,除非是在隊列的尾部。能夠用FLUSH QUERY CACHE語句來清空free blocks Qcache_free_memory:Query Cache 中目前剩餘的內存大小。經過這個參數咱們能夠較爲準確的觀察出當前系統中的Query Cache 內存大小是否足夠,是須要增長仍是過多了。 Qcache_hits:表示有多少次命中緩存。咱們主要能夠經過該值來驗證咱們的查詢緩存的效果。數字越大,緩存效果越理想。 Qcache_inserts:表示多少次未命中而後插入,意思是新來的SQL請求在緩存中未找到,不得不執行查詢處理,執行查詢處理後把結果insert到查詢緩存中。這樣的狀況的次數越多,表示查詢緩存應用到的比較少,效果也就不理想。固然系統剛啓動後,查詢緩存是空的,這很正常。 Qcache_lowmem_prunes:多少條Query 由於內存不足而被清除出Query Cache。經過「Qcache_lowmem_prunes」和「Qcache_free_memory」相互結合,可以更清楚的瞭解到咱們系統中Query Cache 的內存大小是否真的足夠,是否很是頻繁的出現由於內存不足而有Query 被換出。這個數字最好長時間來看;若是這個數字在不斷增加,就表示可能碎片很是嚴重,或者內存不多。(上面的free_blocks和free_memory能夠告訴您屬於哪一種狀況) Qcache_not_cached:不適合進行緩存的查詢的數量,一般是因爲這些查詢不是 SELECT 語句或者用了now()之類的函數。 Qcache_queries_in_cache:當前Query Cache 中cache 的Query 數量; Qcache_total_blocks:當前Query Cache 中的block 數量;。 ------------------------------------- (3)配置示例 mysql> show variables like '%query_cache%' ; +------------------------------+---------+ | Variable_name | Value | +------------------------------+---------+ | have_query_cache | YES | | query_cache_limit | 1048576 | | query_cache_min_res_unit | 4096 | | query_cache_size | 1048576 | | query_cache_type | OFF | | query_cache_wlock_invalidate | OFF | +------------------------------+---------+ 6 rows in set (0.00 sec) mysql> -------------------配置說明------------------------------- 以上信息能夠看出query_cache_type爲off表示不緩存任何查詢 各字段的解釋: query_cache_limit:超過此大小的查詢將不緩存 query_cache_min_res_unit:緩存塊的最小大小,query_cache_min_res_unit的配置是一柄」雙刃劍」,默認是4KB,設置值大對大數據查詢有好處,但若是你的查詢都是小數據查詢,就容易形成內存碎片和浪費。 query_cache_size:查詢緩存大小 (注:QC存儲的最小單位是1024byte,因此若是你設定了一個不是1024的倍數的值,這個值會被四捨五入到最接近當前值的等於1024的倍數的值。) query_cache_type:緩存類型,決定緩存什麼樣的查詢,注意這個值不能隨便設置,必須設置爲數字,可選項目以及說明以下: 若是設置爲0,那麼能夠說,你的緩存根本就沒有用,至關於禁用了。 若是設置爲1,將會緩存全部的結果,除非你的select語句使用SQL_NO_CACHE禁用了查詢緩存。 若是設置爲2,則只緩存在select語句中經過SQL_CACHE指定須要緩存的查詢。 修改/etc/my.cnf,配置完後的部分文件以下: query_cache_size=256M query_cache_type=1 ----------------------------------------------------- 1.6 max_connect_errors max_connect_errors是一個mysql中與安全有關的計數器值,它負責阻止過多嘗試失敗的客戶端以防止暴力破解密碼等狀況,當超過指定次數,mysql服務器將禁止host的鏈接請求,直到mysql服務器重啓或經過flush hosts命令清空此host的相關信息 max_connect_errors的值與性能並沒有太大關係。 修改/etc/my.cnf文件,在[mysqld]下面添加以下內容 max_connect_errors=2000 1.7 sort_buffer_size (1)簡介: 每一個須要進行排序的線程分配該大小的一個緩衝區。增長這值加速ORDER BY 或GROUP BY操做, (2)配置依據 Sort_Buffer_Size並非越大越好,因爲是connection級的參數,過大的設置+高併發可能會耗盡系統內存資源。 列如:500個鏈接將會消耗500*sort_buffer_size(2M)=1G內存 (3)配置方法 修改/etc/my.cnf文件,在[mysqld]下面添加以下: sort_buffer_size=1M 1.8 max_allowed_packet (1)簡介: mysql根據配置文件會限制,server接受的數據包大小。 (2)配置依據: 有時候大的插入和更新會受max_allowed_packet參數限制,致使寫入或者更新失敗,更大值是1GB,必須設置1024的倍數 (3)配置方法: max_allowed_packet=32M 1.9 join_buffer_size 用於表間關聯緩存的大小,和sort_buffer_size同樣,該參數對應的分配內存也是每一個鏈接獨享。 1.10 thread_cache_size (1)簡介 服務器線程緩存,這個值表示能夠從新利用保存在緩存中線程的數量,當斷開鏈接時,那麼客戶端的線程將被放到緩存中以響應下一個客戶而不是銷燬(前提是緩存數未達上限),若是線程從新被請求,那麼請求將從緩存中讀取,若是緩存中是空的或者是新的請求,那麼這個線程將被從新建立,若是有不少新的線程,增長這個值能夠改善系統性能. (2)配置依據 經過比較 Connections 和 Threads_created 狀態的變量,能夠看到這個變量的做用。 設置規則以下:1GB 內存配置爲8,2GB配置爲16,3GB配置爲32,4GB或更高內存,可配置更大。 服務器處理此客戶的線程將會緩存起來以響應下一個客戶而不是銷燬(前提是緩存數未達上限) 試圖鏈接到MySQL(無論是否鏈接成功)的鏈接數 mysql> show status like 'threads_%'; +-------------------+-------+ | Variable_name | Value | +-------------------+-------+ | Threads_cached | 8 | | Threads_connected | 2 | | Threads_created | 4783 | | Threads_running | 1 | +-------------------+-------+ 4 rows in set (0.00 sec) Threads_cached :表明當前此時此刻線程緩存中有多少空閒線程。 Threads_connected :表明當前已創建鏈接的數量,由於一個鏈接就須要一個線程,因此也能夠當作當前被使用的線程數。 Threads_created:表明從最近一次服務啓動,已建立線程的數量,若是發現Threads_created值過大的話,代表MySQL服務器一直在建立線程,這也是比較耗資源,能夠適當增長配置文件中thread_cache_size值。 Threads_running :表明當前激活的(非睡眠狀態)線程數。並非表明正在使用的線程數,有時候鏈接已創建,可是鏈接處於sleep狀態。 (3)配置方法: thread_cache_size=32 1.11 innodb_buffer_pool_size (1)簡介 對於InnoDB表來講,innodb_buffer_pool_size的做用就至關於key_buffer_size對於MyISAM表的做用同樣。 (2)配置依據: InnoDB使用該參數指定大小的內存來緩衝數據和索引。 對於單獨的MySQL數據庫服務器,最大能夠把該值設置成物理內存的80%,通常咱們建議不要超過物理內存的70%。 mysql> SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool%' +---------------------------------------+-------------+ | Variable_name | Value | +---------------------------------------+-------------+ | Innodb_buffer_pool_dump_status | not started | | Innodb_buffer_pool_load_status | not started | | Innodb_buffer_pool_pages_data | 1557 | | Innodb_buffer_pool_bytes_data | 25509888 | | Innodb_buffer_pool_pages_dirty | 0 | | Innodb_buffer_pool_bytes_dirty | 0 | | Innodb_buffer_pool_pages_flushed | 2305 | | Innodb_buffer_pool_pages_free | 63977 | | Innodb_buffer_pool_pages_misc | 2 | | Innodb_buffer_pool_pages_total | 65536 | | Innodb_buffer_pool_read_ahead_rnd | 0 | | Innodb_buffer_pool_read_ahead | 64 | | Innodb_buffer_pool_read_ahead_evicted | 0 | | Innodb_buffer_pool_read_requests | 32036288 | | Innodb_buffer_pool_reads | 600 | | Innodb_buffer_pool_wait_free | 0 | | Innodb_buffer_pool_write_requests | 280891 | +---------------------------------------+-------------+ 17 rows in set (0.00 sec) mysql> Innodb_buffer_pool_pages_data The number of pages in the InnoDB buffer pool containing data. The number includes both dirty and clean pages. Innodb_buffer_pool_pages_total The total size of the InnoDB buffer pool, in pages. Innodb_page_size InnoDB page size (default 16KB). Many values are counted in pages; the page size enables them to be easily converted to bytes (3)配置方法 innodb_buffer_pool_size=1024M 1.12 innodb_flush_log_at_trx_commit (1)簡介 主要控制了innodb將log buffer中的數據寫入日誌文件並flush磁盤的時間點,取值分別爲0、一、2三個。 0,表示當事務提交時,不作日誌寫入操做,而是每秒鐘將log buffer中的數據寫入日誌文件並flush磁盤一次; 1,則在每秒鐘或是每次事物的提交都會引發日誌文件寫入、flush磁盤的操做,確保了事務的ACID; 2,每次事務提交引發寫入日誌文件的動做,但每秒鐘完成一次flush磁盤操做。 (2)配置依據 實際測試發現,該值對插入數據的速度影響很是大,設置爲2時插入10000條記錄只須要2秒,設置爲0時只須要1秒,而設置爲1時則須要229秒。所以,MySQL手冊也建議儘可能將插入操做合併成一個事務,這樣能夠大幅提升速度。 根據MySQL官方文檔,在容許丟失最近部分事務的危險的前提下,能夠把該值設爲0或2。 (3)配置方法 innodb_flush_log_at_trx_commit=1 1.13 innodb_thread_concurrency (1)簡介 此參數用來設置innodb線程的併發數量,默認值爲0表示不限制。 (2)配置依據 在官方doc上,對於innodb_thread_concurrency的使用,也給出了一些建議,以下: 若是一個工做負載中,併發用戶線程的數量小於64,建議設置innodb_thread_concurrency=0; 若是工做負載一直較爲嚴重甚至偶爾達到頂峯,建議先設置innodb_thread_concurrency=128, 並經過不斷的下降這個參數,96, 80, 64等等,直到發現可以提供最佳性能的線程數, 例如,假設系統一般有40到50個用戶,但按期的數量增長至60,70,甚至200。你會發現, 性能在80個併發用戶設置時表現穩定,若是高於這個數,性能反而降低。在這種狀況下, 建議設置innodb_thread_concurrency參數爲80,以免影響性能。 若是你不但願InnoDB使用的虛擬CPU數量比用戶線程使用的虛擬CPU更多(好比20個虛擬CPU), 建議經過設置innodb_thread_concurrency 參數爲這個值(也可能更低,這取決於性能體現), 若是你的目標是將MySQL與其餘應用隔離,你能夠考慮綁定mysqld進程到專有的虛擬CPU。 可是需 要注意的是,這種綁定,在myslqd進程一直不是很忙的狀況下,可能會致使非最優的硬件使用率。在這種狀況下, 你可能會設置mysqld進程綁定的虛擬 CPU,容許其餘應用程序使用虛擬CPU的一部分或所有。 在某些狀況下,最佳的innodb_thread_concurrency參數設置能夠比虛擬CPU的數量小。 按期檢測和分析系統,負載量、用戶數或者工做環境的改變可能都須要對innodb_thread_concurrency參數的設置進行調整。 (3)配置方法: innodb_thread_concurrency=8 1.14 innodb_log_buffer_size 此參數肯定些日誌文件所用的內存大小,以M爲單位。緩衝區更大能提升性能,對於較大的事務,能夠增大緩存大小。 innodb_log_buffer_size=8M 1.15. innodb_log_file_size = 50M 此參數肯定數據日誌文件的大小,以M爲單位,更大的設置能夠提升性能. 1.16. innodb_log_files_in_group = 3 爲提升性能,MySQL能夠以循環方式將日誌文件寫到多個文件。推薦設置爲3 1.17.read_buffer_size = 1M MySql讀入緩衝區大小。對錶進行順序掃描的請求將分配一個讀入緩衝區,MySql會爲它分配一段內存緩衝區。若是對錶的順序掃描請求很是頻繁,而且你認爲頻繁掃描進行得太慢,能夠經過增長該變量值以及內存緩衝區大小提升其性能。和 sort_buffer_size同樣,該參數對應的分配內存也是每一個鏈接獨享 18.read_rnd_buffer_size = 1M MySql的隨機讀(查詢操做)緩衝區大小。當按任意順序讀取行時(例如,按照排序順序),將分配一個隨機讀緩存區。進行排序查詢時,MySql會首先掃描一遍該緩衝,以免磁盤搜索,提升查詢速度,若是須要排序大量數據,可適當調高該值。但MySql會爲每一個客戶鏈接發放該緩衝空間,因此應儘可能適當設置該值,以免內存開銷過大。 注:順序讀是指根據索引的葉節點數據就能順序地讀取所須要的行數據。隨機讀是指通常須要根據輔助索引葉節點中的主鍵尋找實際行數據,而輔助索引和主鍵所在的數據段不一樣,所以訪問方式是隨機的。 19.bulk_insert_buffer_size = 8M 批量插入數據緩存大小,能夠有效提升插入效率,默認爲8M 1.20.binary log log-bin=/data/mysql-bin binlog_cache_size = 2M //爲每一個session 分配的內存,在事務過程當中用來存儲二進制日誌的緩存, 提升記錄bin-log的效率。沒有什麼大事務,dml也不是很頻繁的狀況下能夠設置小一點,若是事務大並且多,dml操做也頻繁,則能夠適當的調大一點。前者建議是--1M,後者建議是:即 2--4M max_binlog_cache_size = 8M //表示的是binlog 可以使用的最大cache 內存大小 max_binlog_size= 512M //指定binlog日誌文件的大小,若是當前的日誌大小達到max_binlog_size,還會自動建立新的二進制日誌。你不能將該變量設置爲大於1GB或小於4096字節。默認值是1GB。在導入大容量的sql文件時,建議關閉sql_log_bin,不然硬盤扛不住,並且建議按期作刪除。 expire_logs_days = 7 //定義了mysql清除過時日誌的時間。 二進制日誌自動刪除的天數。默認值爲0,表示「沒有自動刪除」。 innodb_max_dirty_pages_pct *********** innodb_additional_mem_pool_size (於2G內存的機器,推薦值是20M。32G內存的?100M) transaction_isolation ********* 1.21 安全參數 Innodb_flush_method=(O_DIRECT, fdatasync) 一、fdatasync : (1)在數據頁須要持久化時,首先將數據寫入OS buffer中,而後由os決定何時寫入磁盤 (2)在redo buffuer須要持久化時,首先將數據寫入OS buffer中,而後由os決定何時寫入磁盤 但,若是innodb_flush_log_at_trx_commit=1的話,日誌仍是直接每次commit直接寫入磁盤 二、 Innodb_flush_method=O_DIRECT (1)在數據頁須要持久化時,直接寫入磁盤 (2)在redo buffuer須要持久化時,首先將數據寫入OS buffer中,而後由os決定何時寫入磁盤 但,若是innodb_flush_log_at_trx_commit=1的話,日誌仍是直接每次commit直接寫入磁盤 最高安全模式: innodb_flush_log_at_trx_commit=1 innodb_flush_method=O_DIRECT 最高性能模式: innodb_flush_log_at_trx_commit=0 innodb_flush_method=fdatasync 通常狀況下,咱們更偏向於安全。 「雙一標準」 innodb_flush_log_at_trx_commit=1 *************** sync_binlog=1 *************** innodb_flush_method=O_DIRECT 3、參數優化結果 [mysqld] basedir=/application/mysql datadir=/application/mysql/data socket=/tmp/mysql.sock log-error=/var/log/mysql.log log_bin=/data/binlog/mysql-bin binlog_format=row skip-name-resolve server-id=52 gtid-mode=on enforce-gtid-consistency=true log-slave-updates=1 relay_log_purge=0 max_connections=1024 back_log=128 wait_timeout=60 interactive_timeout=7200 key_buffer_size=16M query_cache_size=64M query_cache_type=1 query_cache_limit=50M max_connect_errors=20 sort_buffer_size=2M max_allowed_packet=32M join_buffer_size=2M thread_cache_size=200 innodb_buffer_pool_size=1024M innodb_flush_log_at_trx_commit=1 innodb_log_buffer_size=32M innodb_log_file_size=128M innodb_log_files_in_group=3 binlog_cache_size=2M max_binlog_cache_size=8M max_binlog_size=512M expire_logs_days=7 read_buffer_size=2M read_rnd_buffer_size=2M bulk_insert_buffer_size=8M [client] socket=/tmp/mysql.sock 再次壓力測試 : [root@db02 ~]# mysqlslap --defaults-file=/etc/my.cnf \ > --concurrency=100 --iterations=1 --create-schema='test1' \ > --query='select * from test1.tb1' engine=innodb \ > --number-of-queries=2000 -uroot -p123 -verbose Warning: Using a password on the command line interface can be insecure. Benchmark Running for engine rbose Average number of seconds to run all queries: 7.271 seconds Minimum number of seconds to run all queries: 7.271 seconds Maximum number of seconds to run all queries: 7.271 seconds Number of clients running queries: 100 Average number of queries per client: 20 對比以前: mysqlslap --defaults-file=/etc/my.cnf \ --concurrency=100 --iterations=1 --create-schema='test1' \ --query='select * from test1.tb1' engine=innodb \ --number-of-queries=2000 -uroot -p123 -verbose Benchmark Running for engine rbose Average number of seconds to run all queries: 31.463 seconds Minimum number of seconds to run all queries: 31.463 seconds Maximum number of seconds to run all queries: 31.463 seconds Number of clients running queries: 100 Average number of queries per client: 20