MySQL資料庫伺服器逐漸變慢 該如何分析與解決

awen7916發表於2015-12-25

第一步 檢查系統的狀態

通過作業系統的一些工具檢查系統的狀態,比如CPU、記憶體、交換、磁碟的利用率,根據經驗或與系統正常時的狀態相比對,有時系統表面上看起來看空閒,這也 可能不是一個正常的狀態,因為cpu可能正等待IO的完成。除此之外,還應觀注那些佔用系統資源(cpu、記憶體)的程式。

1.1 使用sar來檢查作業系統是否存在IO問題

#sar -u 2 10 — 即每隔2秒檢察一次,共執行20次。
結果示例:
注:在redhat下,%system就是所謂的%wio。
Linux 2.4.21-20.ELsmp (YY075) 05/19/2005
10:36:07 AM CPU %user %nice %system %idle
10:36:09 AM all 0.00 0.00 0.13 99.87
10:36:11 AM all 0.00 0.00 0.00 100.00
10:36:13 AM all 0.25 0.00 0.25 99.49
10:36:15 AM all 0.13 0.00 0.13 99.75
10:36:17 AM all 0.00 0.00 0.00 100.00
其中:
Ø %usr指的是使用者程式使用的cpu資源的百分比;
Ø %sys指的是系統資源使用cpu資源的百分比;
Ø %wio指的是等待io完成的百分比,這是值得觀注的一項;
Ø %idle即空閒的百分比。
如果wio列的值很大,如在35%以上,說明系統的IO存在瓶頸,CPU花費了很大的時間去等待I/O的完成。Idle很小說明系統CPU很忙。像以上的示例,可以看到wio平均值為11,說明I/O沒什麼特別的問題,而idle值為零,說明cpu已經滿負荷執行了。

1.2 使用vmstat監控記憶體 cpu資源

[root@mysql1 ~]# vmstat

procs ———–memory———- —swap– —–io—- –system– —–cpu——

r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st

0  0     72  25428  54712 672264    0    0    14    43   53   59  1  1 98  0  0

 

vmstat 的輸出那些資訊值得關注?

io bo: 磁碟寫的資料量稍大,如果是大檔案的寫,10M以內基本不用擔心,如果是小檔案寫2M以內基本正常

 

1.2.1 CPU問題
下面幾列需要被察看,以確定cpu是否有問題
Processes in the run queue (procs r)
User time (cpu us)
System time (cpu sy)
Idle time (cpu id)

問題情況:
1.) 如果processes in run queue (procs r)的數量遠大於系統中cpu的數量,將會使系統便慢。
2.) 如果這個數量是cpu的4倍的話,說明系統正面臨cpu能力短缺,這將使系統執行速度大幅度降低
3.) 如果cpu的idle時間經常為0的話,或者系統佔用時間(cpu sy)是使用者佔用時間(cpu us)兩輩的話,系統面臨缺少cpu資源
解決方案 :
解決這些情況,涉及到調整應用程式,使其能更有效的使用cpu,同時增加cpu的能力或數量

1.2.2記憶體問題
主要檢視頁匯入的數值(swap中的si),如果該值比較大就要考慮記憶體,大概方法如下:
1).最簡單的,加大RAM
2).減少RAM的需求

1.3磁碟IO問題

處理方式:做raid10提高效能

1.4網路問題

telnet一下MySQL對外開放的埠,如果不通的話,看看防火牆是否正確設定了。另外,看看MySQL是不是開啟了skip-networking的選項,如果開啟請關閉。

第二步 檢查mysql引數

2.1 幾個不被注意的mysql引數

2.1.1 max_connect_errors

max_connect_errors預設值為10,如果受信帳號錯誤連線次數達到10則自動堵塞,需要flush hosts來解除。如果你得到象這樣的一個錯誤:

Host ’hostname’ is blocked because of many connection errors.

Unblock with ’mysqladmin flush-hosts’

這意味著,mysqld已經得到了大量(max_connect_errors)的主機’hostname’的在中途被中斷了的連線請求。在 max_connect_errors次失敗請求後,mysqld認定出錯了(象來字一個黑客的攻擊),並且阻止該站點進一步的連線,直到某人執行命令 mysqladmin flush-hosts。

內網連線的話,建議設定在10000以上,已避免堵塞,並定期flush hosts。

2.1.2 connect_timeout

指定MySQL服務等待應答一個連線報文的最大秒數,超出該時間,MySQL向客戶端返回 bad handshake。預設值是5秒,在內網高併發環境中建議設定到10-15秒,以便避免bad hand shake。建議同時關注thread_cache_size並設定thread_cache_size為非0值,大小具體調整。

2.1.3 skip-name-resolve

skip-name-resolve能大大加快使用者獲得連線的速度,特別是在網路情況較差的情況下。MySQL在收到連線請求的時候,會根據請求包中獲得 的ip來反向追查請求者的主機名。然後再根據返回的主機名又一次去獲取ip。如果兩次獲得的ip相同,那麼連線就成功建立了。在DNS不穩定或者區域網內 主機過多的情況下,一次成功的連線將會耗費很多不必要的時間。假如MySQL伺服器的ip地址是廣域網的,最好不要設定skip-name- resolve。

2.1.4 slave-net-timeout=seconds

引數含義:當slave從主資料庫讀取log資料失敗後,等待多久重新建立連線並獲取資料。預設值是3600秒,如果需要保證同步性,如此NC的引數請極力控制在10秒以下。

2.1.5 master-connect-retry

引數含義:當重新建立主從連線時,如果連線建立失敗,間隔多久後重試。預設是60秒,請按照合理的情況去設定引數。

 

第三步 檢查mysql 相關狀態值

3.1關注連線數

如果連線數達到了最大連線數,那不管 有多少資源,使用者都會阻塞在外面。

修改mysql最大連線數:

開啟my.ini,修改max_connections=100(預設為100)。

請根據硬體情況調整到合適的大小,一般經驗值可設為3000。Windows伺服器大概支援量為1500-1800個連線,linux伺服器可以支援到8000個左右。

請將max_user_connections設0——–這個0代表不限制單使用者的最大連線數,其最大連線值可以等於max_connections值。

mysql> show global status like ‘Max_used_connections’;

檢查下最大的過往使用連線數,這個值在max_connections的85%左右是比較合適的,如果過高則是max_connections過少或者系統負荷過高了。

 

3.1.1 mysqladmin -uroot status

[root@mysql1 ~]# mysqladmin -uroot status

Uptime: 1742276  Threads: 2  Questions: 2538  Slow queries: 0  Opens: 145  Flush tables: 1  Open tables: 23  Queries per second avg: 0.1

3.1.2 show full processlist

1.顯示所有程式

mysql> show full processlist;

+—–+——+———–+——+———+——+——-+———————–+

| Id  | User | Host      | db   | Command | Time | State | Info                  |

+—–+——+———–+——+———+——+——-+———————–+

| 629 | root | localhost | NULL | Query   |    0 | NULL  | show full processlist |

| 633 | root | localhost | NULL | Sleep   |   11 |       | NULL                  |

+—–+——+———–+——+———+——+——-+———————–+

2 rows in set (0.00 sec)

 

2.如果正在執行的語句太多,執行時間太長,表示MySQL效率有問題。必要的時候可以將對應的程式kill掉。

殺死休眠的程式kill ID號

mysql> kill 633;

Query OK, 0 rows affected (0.00 sec)

 

3.關注TIME引數,看看正在執行的使用者程式有多少是長時間佔用的,具體分析下。

3.1.3使用mysqlreport關注Connections,Threads

__ Connections _________________________________________________________

Max used            3 of  200      %Max:   1.50

Total          30.16k     0.7/s

。。。。。。

__ Threads _____________________________________________________________

Running             1 of    2

Cached              1 of  300      %Hit:  99.99

Created             3     0.0/s

Slow                0       0/s

3.2關注下系統鎖情況

3.2.1 mysql> show status like ‘%lock%’;

+——————————-+———+

| Variable_name                 | Value   |

+——————————-+———+

| Com_lock_tables               | 0       |

| Com_unlock_tables             | 0       |

| Innodb_row_lock_current_waits | 0       |

| Innodb_row_lock_time          | 0       |

| Innodb_row_lock_time_avg      | 0       |

| Innodb_row_lock_time_max      | 0       |

| Innodb_row_lock_waits         | 0       |

| Table_locks_immediate         | 2667760 |

| Table_locks_waited            | 0       |

   

3.2.2使用mysqlreport關注Table Locks,InnoDB Lock

__ Questions ___________________________________________________________

Total           3.38M    81.4/s

DMS           2.88M    69.3/s  %Total:  85.11

QC Hits     382.70k     9.2/s           11.32

Com_         90.50k     2.2/s            2.68

COM_QUIT     30.15k     0.7/s            0.89

+Unknown         18     0.0/s            0.00

Slow 1 s           92     0.0/s            0.00  %DMS:   0.00  Log: OFF

。。。。。。

__ Table Locks _________________________________________________________

Waited              0       0/s  %Total:   0.00

Immediate       2.67M    64.2/s

。。。。。。

__ InnoDB Lock _________________________________________________________

Waits               0       0/s

Current             0

Time acquiring

Total             0 ms

Average           0 ms

Max               0 ms

。。。。。。

如果wait過多,平均時間過長,那就是查詢設計的有問題,仔細關注下超長時間的查詢,並開啟slow_query_log。

3.3 關注慢查詢(slow query)日誌

日誌必然會拖慢系統速度,特別是CPU資源,所以如果CPU資源充分,可以一直開啟,如果不充足,那就在需要調整的時候,或者在replication從伺服器上開啟(針對select)

mysql> show variables like ‘%slow%’;

+———————+—————————————-+

| Variable_name       | Value                                  |

+———————+—————————————-+

| log_slow_queries    | OFF                                    |

| slow_launch_time    | 2                                      |

| slow_query_log      | OFF                                    |

| slow_query_log_file | /data0/mysql/3306/data/mysql1-slow.log |

+———————+—————————————-+

4 rows in set (0.00 sec)

 

mysql> set  GLOBAL slow_query_log=on;

Query OK, 0 rows affected (0.00 sec)

3.3.1關注慢查詢涉及的表的相關狀態

1.       表內記錄數。儘量控制在500萬行以內(有索引),建議控制在200萬行

2.       表內索引的使用。

3.       表如果update,delete,insert頻繁,可以考慮optimize table優化下檔案存放,索引,儲存空間。

4.       表內update,insert,delete查詢的鎖定時間。

5.       select for update如果條件欄位無索引的話,會引起的是鎖全表而不是行鎖,請關注。

6.       如果查詢包括GROUP BY但你想要避免排序結果的消耗,你可以指定ORDER BY NULL禁止排序。

3.3.2定期分析表

ANALYZE TABLE

語法:

ANALYZE [LOCAL | NO_WRITE_TO_BINLOG] TABLE tbl_name [, tbl_name] …

本語句用於分析和儲存表的關鍵字分佈。在分析期間,使用一個讀取鎖定對錶進行鎖定。這對於MyISAM, BDB和InnoDB表有作用。對於MyISAM表,本語句與使用myisamchk -a相當。

CHECK TABLE

語法:

CHECK TABLE tbl_name [, tbl_name] … [option] …

option = {QUICK | FAST | MEDIUM | EXTENDED | CHANGED}

檢查一個或多個表是否有錯誤。CHECK TABLE對MyISAM和InnoDB表有作用。對於MyISAM表,關鍵字統計資料被更新。

CHECK TABLE也可以檢查檢視是否有錯誤,比如在檢視定義中被引用的表已不存在。

CHECKSUM TABLE

語法:

CHECKSUM TABLE tbl_name [, tbl_name] … [ QUICK | EXTENDED ]

報告一個表校驗和。

3.3.3使用optimize table

OPTIMIZE TABLE

語法:

OPTIMIZE [LOCAL | NO_WRITE_TO_BINLOG] TABLE tbl_name [, tbl_name] …

如果已經刪除了表的一大部分,或者如果您已經對含有可變長度行的表(含有VARCHAR, BLOB或TEXT列的表)進行了很多更改,則應使用OPTIMIZE TABLE。被刪除的記錄被保持在連結清單中,後續的INSERT操作會重新使用舊的記錄位置。您可以使用OPTIMIZE TABLE來重新利用未使用的空間,並整理資料檔案的碎片。

OPTIMIZE TABLE只對MyISAM, BDB和InnoDB表起作用。

 

附錄:

一.Sar命令獲得

安裝sysstat 系統狀態包

[root@mysql1 ~]# yum info sysstat

Loaded plugins: fastestmirror

Loading mirror speeds from cached hostfile

Installed Packages

Name       : sysstat

Arch       : i386

Version    : 7.0.2

Release    : 3.el5

Size       : 383 k

Repo       : installed

Summary    : sar 和 iostat 系統監視命令。

URL        : http://perso.orange.fr/sebastien.godard/

License    : GPL

Description: 該軟體包為 Linux 提供了 sar 和 iostat 工具。sar 和 iostat

: 使系統能夠監視磁碟、網路、以及其它 IO 活動。

:

[root@mysql1 ~]# yum install sysstat

Loaded plugins: fastestmirror

Loading mirror speeds from cached hostfile

Setting up Install Process

Resolving Dependencies

–> Running transaction check

—> Package sysstat.i386 0:7.0.2-3.el5 set to be updated

–> Finished Dependency Resolution

 

Dependencies Resolved

 

============================================================================================

Package              Arch              Version                   Repository           Size

============================================================================================

Installing:

sysstat              i386              7.0.2-3.el5               CentOS              169 k

 

Transaction Summary

============================================================================================

Install      1 Package(s)

Update       0 Package(s)

Remove       0 Package(s)

 

Total download size: 169 k

Is this ok [y/N]: y

Downloading Packages:

sysstat-7.0.2-3.el5.i386.rpm                                         | 169 kB     00:00

Running rpm_check_debug

Running Transaction Test

Finished Transaction Test

Transaction Test Succeeded

Running Transaction

Installing     : sysstat                                                              1/1

 

Installed:

sysstat.i386 0:7.0.2-3.el5

 

Complete!

sar 命令列的常用格式:

 

在linux中使用sar調優系統效能

關鍵字: sar

sar預設在linux下沒有安裝,需要我們手工安裝,一般建議原始碼方式安裝,下載類似sysstat-6.1.3.tar.gz

然後configure make make install即可使用.

sar 命令列的常用格式:

sar [options] [-A] [-o file] t [n]

在命令列中,n 和t 兩個引數組合起來定義取樣間隔和次數,t為取樣間隔,是必須有
的引數,n為取樣次數,是可選的,預設值是1,-o file表示將命令結果以二進位制格式
存放在檔案中,file 在此處不是關鍵字,是檔名。options 為命令列選項,sar命令
的選項很多,下面只列出常用選項:

-A:所有報告的總和。
-u:CPU利用率
-v:程式、I節點、檔案和鎖表狀態。
-d:硬碟使用報告。
-r:沒有使用的記憶體頁面和硬碟塊。
-g:串列埠I/O的情況。
-b:緩衝區使用情況。
-a:檔案讀寫情況。
-c:系統呼叫情況。
-R:程式的活動情況。
-y:終端裝置活動情況。
-w:系統交換活動。

下面將舉例說明。

例一:使用命令列 sar -u t n

例如,每60秒取樣一次,連續取樣5次,觀察CPU 的使用情況,並將取樣結果以二進位制
形式存入當前目錄下的檔案zhou中,需鍵入如下命令:

# sar -u -o zhou 60 5

螢幕顯示:

SCO_SV   scosysv 3.2v5.0.5 i80386   10/01/2001
14:43:50   %usr   %sys  %wio    %idle(-u)
14:44:50   0     1    4      94
14:45:50   0     2    4      93
14:46:50   0     2    2      96
14:47:50   0     2    5      93
14:48:50   0     2    2      96
Average    0     2    4      94

在顯示內容包括:

%usr:CPU處在使用者模式下的時間百分比。
%sys:CPU處在系統模式下的時間百分比。
%wio:CPU等待輸入輸出完成時間的百分比。
%idle:CPU空閒時間百分比。

在所有的顯示中,我們應主要注意%wio和%idle,%wio的值過高,表示硬碟存在I/O瓶頸,
%idle值高,表示CPU較空閒,如果%idle值高但系統響應慢時,有可能是CPU等待分配記憶體,
此時應加大記憶體容量。%idle值如果持續低於10,那麼系統的CPU處理能力相對較低,表
明系統中最需要解決的資源是CPU。

如果要檢視二進位制檔案zhou中的內容,則需鍵入如下sar命令:

# sar -u -f zhou

可見,sar命令即可以實時取樣,又可以對以往的取樣結果進行查詢。

例二:使用命行sar -v t n

例如,每30秒取樣一次,連續取樣5次,觀察核心表的狀態,需鍵入如下命令:

# sar -v 30 5

螢幕顯示:
SCO_SV scosysv 3.2v5.0.5 i80386 10/01/2001
10:33:23 proc-sz ov inod-sz ov file-sz ov lock-sz   (-v)
10:33:53 305/ 321  0 1337/2764  0 1561/1706 0 40/ 128
10:34:23 308/ 321  0 1340/2764  0 1587/1706 0 37/ 128
10:34:53 305/ 321  0 1332/2764  0 1565/1706 0 36/ 128
10:35:23 308/ 321  0 1338/2764  0 1592/1706 0 37/ 128
10:35:53 308/ 321  0 1335/2764  0 1591/1706 0 37/ 128

顯示內容包括:

proc-sz:目前核心中正在使用或分配的程式表的表項數,由核心引數MAX-PROC控制。

inod-sz:目前核心中正在使用或分配的i節點表的表項數,由核心引數
MAX-INODE控制。

file-sz: 目前核心中正在使用或分配的檔案表的表項數,由核心引數MAX-FILE控
制。

ov:溢位出現的次數。

Lock-sz:目前核心中正在使用或分配的記錄加鎖的表項數,由核心引數MAX-FLCKRE
控制。

顯示格式為

實際使用表項/可以使用的表項數

顯示內容表示,核心使用完全正常,三個表沒有出現溢位現象,核心引數不需調整,如
果出現溢位時,要調整相應的核心引數,將對應的表項數加大。

例三:使用命行sar -d t n

例如,每30秒取樣一次,連續取樣5次,報告裝置使用情況,需鍵入如下命令:

# sar -d 30 5

螢幕顯示:

SCO_SV scosysv 3.2v5.0.5 i80386 10/01/2001
11:06:43 device %busy   avque   r+w/s  blks/s  avwait avserv (-d)
11:07:13 wd-0   1.47   2.75   4.67   14.73   5.50 3.14
11:07:43 wd-0   0.43   18.77   3.07   8.66   25.11 1.41
11:08:13 wd-0   0.77   2.78   2.77   7.26   4.94 2.77
11:08:43 wd-0   1.10   11.18   4.10   11.26   27.32 2.68
11:09:13 wd-0   1.97   21.78   5.86   34.06   69.66 3.35
Average wd-0   1.15   12.11   4.09   15.19   31.12 2.80

顯示內容包括:

device: sar命令正在監視的塊裝置的名字。
%busy: 裝置忙時,傳送請求所佔時間的百分比。
avque: 佇列站滿時,未完成請求數量的平均值。
r+w/s: 每秒傳送到裝置或從裝置傳出的資料量。
blks/s: 每秒傳送的塊數,每塊512位元組。
avwait: 佇列佔滿時傳送請求等待佇列空閒的平均時間。
avserv: 完成傳送請求所需平均時間(毫秒)。

在顯示的內容中,wd-0是硬碟的名字,%busy的值比較小,說明用於處理傳送請求的有
效時間太少,檔案系統效率不高,一般來講,%busy值高些,avque值低些,檔案系統
的效率比較高,如果%busy和avque值相對比較高,說明硬碟傳輸速度太慢,需調整。

例四:使用命行sar -b t n

例如,每30秒取樣一次,連續取樣5次,報告緩衝區的使用情況,需鍵入如下命令:

# sar -b 30 5

螢幕顯示:

SCO_SV scosysv 3.2v5.0.5 i80386 10/01/2001
14:54:59 bread/s lread/s %rcache bwrit/s lwrit/s %wcache pread/s pwrit/s (-b)
14:55:29 0  147  100  5  21  78   0   0
14:55:59 0  186  100  5  25  79   0   0
14:56:29 4  232   98  8  58  86   0   0
14:56:59 0  125  100  5  23  76   0   0
14:57:29 0   89  100  4  12  66   0   0
Average  1  156   99  5  28  80   0   0

顯示內容包括:

bread/s: 每秒從硬碟讀入系統緩衝區buffer的物理塊數。
lread/s: 平均每秒從系統buffer讀出的邏輯塊數。
%rcache: 在buffer cache中進行邏輯讀的百分比。
bwrit/s: 平均每秒從系統buffer向磁碟所寫的物理塊數。
lwrit/s: 平均每秒寫到系統buffer邏輯塊數。
%wcache: 在buffer cache中進行邏輯讀的百分比。
pread/s: 平均每秒請求物理讀的次數。
pwrit/s: 平均每秒請求物理寫的次數。

在顯示的內容中,最重要的是%cache和%wcache兩列,它們的值體現著buffer的使用效
率,%rcache的值小於90或者%wcache的值低於65,應適當增加系統buffer的數量,buffer
數量由核心引數NBUF控制,使%rcache達到90左右,%wcache達到80左右。但buffer引數
值的多少影響I/O效率,增加buffer,應在較大記憶體的情況下,否則系統效率反而得不到
提高。

例五:使用命行sar -g t n

例如,每30秒取樣一次,連續取樣5次,報告串列埠I/O的操作情況,需鍵入如下命令:

# sar -g 30 5

螢幕顯示:

SCO_SV scosysv 3.2v5.0.5 i80386  11/22/2001
17:07:03  ovsiohw/s  ovsiodma/s  ovclist/s (-g)
17:07:33   0.00   0.00   0.00
17:08:03   0.00   0.00   0.00
17:08:33   0.00   0.00   0.00
17:09:03   0.00   0.00   0.00
17:09:33   0.00   0.00   0.00
Average    0.00   0.00   0.00

顯示內容包括:

ovsiohw/s:每秒在串列埠I/O硬體出現的溢位。

ovsiodma/s:每秒在串列埠I/O的直接輸入輸出通道快取記憶體出現的溢位。

ovclist/s :每秒字元佇列出現的溢位。

在顯示的內容中,每一列的值都是零,表明在取樣時間內,系統中沒有發生串列埠I/O溢
出現象。

sar命令的用法很多,有時判斷一個問題,需要幾個sar命令結合起來使用,比如,懷疑
CPU存在瓶頸,可用sar -u 和sar -q來看,懷疑I/O存在瓶頸,可用sar -b、sar -u和
sar-d來看,以上舉出的五例僅僅是其中的一部分,有興趣的朋友不妨一試。

本文來自: IXPUB技術社群(www.ixpub.net) 詳細出處參考:http://www.ixpub.net/thread-749930-1-17.html

二.vmstat命令輸出分成六個部分:

(1)程式procs:
r:在執行佇列中等待的程式數 。
b:在等待io的程式數 。
(2)記憶體memoy:
swpd:現時可用的交換記憶體(單位KB)。
free:空閒的記憶體(單位KB)。
buff: 緩衝去中的記憶體數(單位:KB)。
cache:被用來做為快取記憶體的記憶體數(單位:KB)。
(3) swap交換頁面
si: 從磁碟交換到記憶體的交換頁數量,單位:KB/秒。
so: 從記憶體交換到磁碟的交換頁數量,單位:KB/秒。
(4) io塊裝置:
bi: 傳送到塊裝置的塊數,單位:塊/秒。
bo: 從塊裝置接收到的塊數,單位:塊/秒。
(5)system系統:
in: 每秒的中斷數,包括時鐘中斷。
cs: 每秒的環境(上下文)切換次數。
(6)cpu中央處理器:
cs:使用者程式使用的時間 。以百分比表示。
sy:系統程式使用的時間。 以百分比表示。
id:中央處理器的空閒時間 。以百分比表示。
如果 r經常大於 4 ,且id經常小於40,表示中央處理器的負荷很重。 如果bi,bo 長期不等於0,表示實體記憶體容量太小。


三.根據mysql狀態調整系統引數

mysql> show global status;

可以列出MySQL伺服器執行各種狀態值,另外,查詢MySQL伺服器配置資訊語句:

mysql> show variables;

一、慢查詢

mysql> show variables like ‘%slow%’;

+——————+——-+

| Variable_name | Value |

+——————+——-+

| log_slow_queries | ON |

| slow_launch_time | 2 |

+——————+——-+

mysql> show global status like ‘%slow%’;

+———————+——-+

| Variable_name | Value |

+———————+——-+

| Slow_launch_threads | 0 |

| Slow_queries | 4148 |

+———————+——-+

配置中開啟了記錄慢查詢,執行時間超過2秒的即為慢查詢,系統顯示有4148個慢查詢,你可以分析慢查詢日誌,找出有問題的SQL語句,慢查詢時間不宜設 置過長,否則意義不大,最好在5秒以內,如果你需要微秒級別的慢查詢,可以考慮給MySQL打補丁:http://www.percona.com /docs/wiki/release:start,記得找對應的版本。

開啟慢查詢日誌可能會對系統效能有一點點影響,如果你的MySQL是主-從結構,可以考慮開啟其中一臺從伺服器的慢查詢日誌,這樣既可以監控慢查詢,對系統效能影響又小。

二、連線數

經常會遇見”MySQL: ERROR 1040: Too many connections”的情況,一種是訪問量確實很高,MySQL伺服器抗不住,這個時候就要考慮增加從伺服器分散讀壓力,另外一種情況是MySQL配 置檔案中max_connections值過小:

mysql> show variables like ‘max_connections’;

+—————–+——-+

| Variable_name | Value |

+—————–+——-+

| max_connections | 256 |

+—————–+——-+

這臺MySQL伺服器最大連線數是256,然後查詢一下伺服器響應的最大連線數:

mysql> show global status like ‘Max_used_connections’;

MySQL伺服器過去的最大連線數是245,沒有達到伺服器連線數上限256,應該沒有出現1040錯誤,比較理想的設定是:

Max_used_connections / max_connections * 100% ≈ 85%

最大連線數占上限連線數的85%左右,如果發現比例在10%以下,MySQL伺服器連線數上限設定的過高了。

三、Key_buffer_size

key_buffer_size是對MyISAM表效能影響最大的一個引數,下面一臺以MyISAM為主要儲存引擎伺服器的配置:

mysql> show variables like ‘key_buffer_size’;

+—————–+————+

| Variable_name | Value |

+—————–+————+

| key_buffer_size | 536870912 |

+—————–+————+

分配了512MB記憶體給key_buffer_size,我們再看一下key_buffer_size的使用情況:

mysql> show global status like ‘key_read%’;

+————————+————-+

| Variable_name | Value |

+————————+————-+

| Key_read_requests | 27813678764 |

| Key_reads | 6798830 |

+————————+————-+

一共有27813678764個索引讀取請求,有6798830個請求在記憶體中沒有找到直接從硬碟讀取索引,計算索引未命中快取的概率:

key_cache_miss_rate = Key_reads / Key_read_requests * 100%

比如上面的資料,key_cache_miss_rate為0.0244%,4000個索引讀取請求才有一個直接讀硬碟,已經很BT 了,key_cache_miss_rate在0.1%以下都很好(每1000個請求有一個直接讀硬碟),如果key_cache_miss_rate在 0.01%以下的話,key_buffer_size分配的過多,可以適當減少。

MySQL伺服器還提供了key_blocks_*引數:

mysql> show global status like ‘key_blocks_u%’;

+————————+————-+

| Variable_name | Value |

+————————+————-+

| Key_blocks_unused | 0 |

| Key_blocks_used | 413543 |

+————————+————-+

Key_blocks_unused表示未使用的快取簇(blocks)數,Key_blocks_used表示曾經用到的最大的blocks數,比如這 臺伺服器,所有的快取都用到了,要麼增加key_buffer_size,要麼就是過渡索引了,把快取佔滿了。比較理想的設定:

Key_blocks_used / (Key_blocks_unused + Key_blocks_used) * 100% ≈ 80%

四、臨時表

mysql> show global status like ‘created_tmp%’;

+————————-+———+

| Variable_name | Value |

+————————-+———+

| Created_tmp_disk_tables | 21197 |

| Created_tmp_files | 58 |

| Created_tmp_tables | 1771587 |

+————————-+———+

每次建立臨時表,Created_tmp_tables增加,如果是在磁碟上建立臨時表,Created_tmp_disk_tables也增加,Created_tmp_files表示MySQL服務建立的臨時檔案檔案數,比較理想的配置是:

Created_tmp_disk_tables / Created_tmp_tables * 100% <= 25%

比如上面的伺服器Created_tmp_disk_tables / Created_tmp_tables * 100% = 1.20%,應該相當好了。我們再看一下MySQL伺服器對臨時表的配置:

mysql> show variables where Variable_name in (‘tmp_table_size’, ‘max_heap_table_size’);

+———————+———–+

| Variable_name | Value |

+———————+———–+

| max_heap_table_size | 268435456 |

| tmp_table_size | 536870912 |

+———————+———–+

只有256MB以下的臨時表才能全部放記憶體,超過的就會用到硬碟臨時表。

五、Open Table情況

mysql> show global status like ‘open%tables%’;

+—————+——-+

| Variable_name | Value |

+—————+——-+

| Open_tables | 919 |

| Opened_tables | 1951 |

+—————+——-+

Open_tables表示開啟表的數量,Opened_tables表示開啟過的表數量,如果Opened_tables數量過大,說明配置中 table_cache(5.1.3之後這個值叫做table_open_cache)值可能太小,我們查詢一下伺服器table_cache值:

mysql> show variables like ‘table_cache’;

+—————+——-+

| Variable_name | Value |

+—————+——-+

| table_cache | 2048 |

+—————+——-+

比較合適的值為:

Open_tables / Opened_tables * 100% >= 85%

Open_tables / table_cache * 100% <= 95%

六、程式使用情況

mysql> show global status like ‘Thread%’;

+——————-+——-+

| Variable_name | Value |

+——————-+——-+

| Threads_cached | 46 |

| Threads_connected | 2 |

| Threads_created | 570 |

| Threads_running | 1 |

+——————-+——-+

如果我們在MySQL伺服器配置檔案中設定了thread_cache_size,當客戶端斷開之後,伺服器處理此客戶的執行緒將會快取起來以響應下一個客 戶而不是銷燬(前提是快取數未達上限)。Threads_created表示建立過的執行緒數,如果發現Threads_created值過大的話,表明 MySQL伺服器一直在建立執行緒,這也是比較耗資源,可以適當增加配置檔案中thread_cache_size值,查詢伺服器 thread_cache_size配置:

mysql> show variables like ‘thread_cache_size’;

+——————-+——-+

| Variable_name | Value |

+——————-+——-+

| thread_cache_size | 64 |

+——————-+——-+

示例中的伺服器還是挺健康的。

七、查詢快取(query cache)

mysql> show global status like ‘qcache%’;

+————————-+———–+

| Variable_name | Value |

+————————-+———–+

| Qcache_free_blocks | 22756 |

| Qcache_free_memory | 76764704 |

| Qcache_hits | 213028692 |

| Qcache_inserts | 208894227 |

| Qcache_lowmem_prunes | 4010916 |

| Qcache_not_cached | 13385031 |

| Qcache_queries_in_cache | 43560 |

| Qcache_total_blocks | 111212 |

+————————-+———–+

MySQL查詢快取變數解釋:

Qcache_free_blocks:快取中相鄰記憶體塊的個數。數目大說明可能有碎片。FLUSH QUERY CACHE會對快取中的碎片進行整理,從而得到一個空閒塊。

Qcache_free_memory:快取中的空閒記憶體。

Qcache_hits:每次查詢在快取中命中時就增大

Qcache_inserts:每次插入一個查詢時就增大。命中次數除以插入次數就是不中比率。

Qcache_lowmem_prunes:快取出現記憶體不足並且必須要進行清理以便為更多查詢提供空間的次數。這個數字最好長時間來看;如果這個數字在 不斷增長,就表示可能碎片非常嚴重,或者記憶體很少。(上面的 free_blocks和free_memory可以告訴您屬於哪種情況)

Qcache_not_cached:不適合進行快取的查詢的數量,通常是由於這些查詢不是 SELECT 語句或者用了now()之類的函式。

Qcache_queries_in_cache:當前快取的查詢(和響應)的數量。

Qcache_total_blocks:快取中塊的數量。

我們再查詢一下伺服器關於query_cache的配置:

mysql> show variables like ‘query_cache%’;

+——————————+———–+

| Variable_name | Value |

+——————————+———–+

| query_cache_limit | 2097152 |

| query_cache_min_res_unit | 4096 |

| query_cache_size | 203423744 |

| query_cache_type | ON |

| query_cache_wlock_invalidate | OFF |

+——————————+———–+

各欄位的解釋:

query_cache_limit:超過此大小的查詢將不快取

query_cache_min_res_unit:快取塊的最小大小

query_cache_size:查詢快取大小

query_cache_type:快取型別,決定快取什麼樣的查詢,示例中表示不快取 select sql_no_cache 查詢

query_cache_wlock_invalidate:當有其他客戶端正在對MyISAM表進行寫操作時,如果查詢在query cache中,是否返回cache結果還是等寫操作完成再讀表獲取結果。

query_cache_min_res_unit的配置是一柄”雙刃劍”,預設是4KB,設定值大對大資料查詢有好處,但如果你的查詢都是小資料查詢,就容易造成記憶體碎片和浪費。

查詢快取碎片率 = Qcache_free_blocks / Qcache_total_blocks * 100%

如果查詢快取碎片率超過20%,可以用FLUSH QUERY CACHE整理快取碎片,或者試試減小query_cache_min_res_unit,如果你的查詢都是小資料量的話。

查詢快取利用率 = (query_cache_size – Qcache_free_memory) / query_cache_size * 100%

查詢快取利用率在25%以下的話說明query_cache_size設定的過大,可適當減小;查詢快取利用率在80%以上而且Qcache_lowmem_prunes > 50的話說明query_cache_size可能有點小,要不就是碎片太多。

查詢快取命中率 = (Qcache_hits – Qcache_inserts) / Qcache_hits * 100%

示例伺服器 查詢快取碎片率 = 20.46%,查詢快取利用率 = 62.26%,查詢快取命中率 = 1.94%,命中率很差,可能寫操作比較頻繁吧,而且可能有些碎片。

八、排序使用情況

mysql> show global status like ‘sort%’;

+——————-+————+

| Variable_name | Value |

+——————-+————+

| Sort_merge_passes | 29 |

| Sort_range | 37432840 |

| Sort_rows | 9178691532 |

| Sort_scan | 1860569 |

+——————-+————+

Sort_merge_passes 包括兩步。MySQL 首先會嘗試在記憶體中做排序,使用的記憶體大小由系統變數 Sort_buffer_size 決定,如果它的大小不夠把所有的記錄都讀到記憶體中,MySQL 就會把每次在記憶體中排序的結果存到臨時檔案中,等 MySQL 找到所有記錄之後,再把臨時檔案中的記錄做一次排序。這再次排序就會增加 Sort_merge_passes。實際上,MySQL 會用另一個臨時檔案來存再次排序的結果,所以通常會看到 Sort_merge_passes 增加的數值是建臨時檔案數的兩倍。因為用到了臨時檔案,所以速度可能會比較慢,增加 Sort_buffer_size 會減少 Sort_merge_passes 和 建立臨時檔案的次數。但盲目的增加 Sort_buffer_size 並不一定能提高速度,見 How fast can you sort data with MySQL?(引自http://qroom.blogspot.com/2007/09/mysql-select-sort.html,貌似被牆)

另外,增加read_rnd_buffer_size(3.2.3是record_rnd_buffer_size)的值對排序的操作也有一點的好處,參 見:http://www.mysqlperformanceblog.com/2007/07/24/what-exactly-is- read_rnd_buffer_size/

九、檔案開啟數(open_files)

mysql> show global status like ‘open_files’;

+—————+——-+

| Variable_name | Value |

+—————+——-+

| Open_files | 1410 |

+—————+——-+

mysql> show variables like ‘open_files_limit’;

+——————+——-+

| Variable_name | Value |

+——————+——-+

| open_files_limit | 4590 |

+——————+——-+

比較合適的設定:Open_files / open_files_limit * 100% <= 75%

十、表鎖情況

mysql> show global status like ‘table_locks%’;

+———————–+———–+

| Variable_name | Value |

+———————–+———–+

| Table_locks_immediate | 490206328 |

| Table_locks_waited | 2084912 |

+———————–+———–+

Table_locks_immediate表示立即釋放表鎖數,Table_locks_waited表示需要等待的表鎖數,如果 Table_locks_immediate / Table_locks_waited > 5000,最好採用InnoDB引擎,因為InnoDB是行鎖而MyISAM是表鎖,對於高併發寫入的應用InnoDB效果會好些。示例中的伺服器 Table_locks_immediate / Table_locks_waited = 235,MyISAM就足夠了。

十一、表掃描情況

mysql> show global status like ‘handler_read%’;

+———————–+————-+

| Variable_name | Value |

+———————–+————-+

| Handler_read_first | 5803750 |

| Handler_read_key | 6049319850 |

| Handler_read_next | 94440908210 |

| Handler_read_prev | 34822001724 |

| Handler_read_rnd | 405482605 |

| Handler_read_rnd_next | 18912877839 |

+———————–+————-+

各欄位解釋參見http://hi.baidu.com/thinkinginlamp/blog/item/31690cd7c4bc5cdaa144df9c.html,調出伺服器完成的查詢請求次數:

mysql> show global status like ‘com_select’;

+—————+———–+

| Variable_name | Value |

+—————+———–+

| Com_select | 222693559 |

+—————+———–+

計算表掃描率:

表掃描率 = Handler_read_rnd_next / Com_select

如果表掃描率超過4000,說明進行了太多表掃描,很有可能索引沒有建好,增加read_buffer_size值會有一些好處,但最好不要超過8MB。

相關文章