mysql與系統優化

1.系統優化工具

1.1 top

實時監控當前操做系統的負載狀況的,每秒刷新一次狀態,一般會關注三大指標(CPU、MEM、IO)mysql

1.1.1 各項指標說明

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

1.2 iostat

測試當前環境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自己問題)

1.3 vmstat

[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

1.4 dstat

須要手動安裝: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

2.數據庫層面優化工具

基礎優化命令工具
(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默認開啓)

3.硬件優化

主機:
根據數據庫類型
(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(主備)

4.系統層面優化

一、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
以上:硬件優化建議,操做系統優化建議,應該在業務架構搭建初始應該作好。

5.數據庫層面優化

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
相關文章
相關標籤/搜索