mysqlreport是一個腳本.
需要先安裝perl-DBI和perl-DBD-MySQL這2個包
?mysqlreport 使用
DBI 需要有
http://hackmysql.com/mysqlreportdoc
perl ./mysqlreport --help 看幫助
perl ./mysqlreport --user root --password 密碼
mysqlreport 文檔
mysqlreport 以很友好的方式顯示 MySQL狀態變。事實上,它幾乎報告了所有的狀態。不像 SHOW STATUS 只是在顯示了100多個狀態值,mysqlreport 則以人性化的方式闡釋和格式化了這些狀態值,大大增加了其可讀性。可以 點擊這里 查看mysqlreport的例子。
mysqlreport 的好處是可以快速的查看各種狀態參數組,從而了解服務器的運行狀態情況,而無需從 SHOW STATUS 的結果中人工計算。例如索引讀取比率是個重要的參數,但是 SHOW STATUS 中并沒有顯示;它是一個推斷值(key_reads 和 key_read_requests 的比值)。
本文檔描述了 mysqlreport 的所有命令行選項,大部分是用于控制如何顯示結果的。本文并沒有解釋這些推斷值是怎么計算得到的,可以點擊 理解mysqlreport 查看具體的計算方法。
注意
命令行選項的格式是 --選項,不過 -選項 的格式也可以。所有的選項都有其縮寫,只要是唯一的。例如,選項 --host 可以縮寫成 --ho,不過不能寫成 --h,因為 --h 有歧義,可能是 --host 或者 --help。
選項列表
--user USER
--password
--host ADDRESS
--port PORT
--socket SOCKET
--no-mycnf
--help???????? 這些選項是模擬其他標準應用程序的。從 2.3 版本開始,--password 可以在后面加上參數,如 "--password FOO"。如果命令行中只指定了選項 --password,則會提示輸入密碼。--no-mycnf 告訴 mysqlreport 不要讀取 ~/.my.cnf,默認會去讀取這個文件。--user 和 --password 總是覆蓋從 ~/.my.cnf 中取得的結果。
--infile FILE???????? 直接從文件中讀取狀態文件,而不是從MySQL的 SHOW STATUS 中讀取。文件內容通常是從 SHOW STATUS 的結果中取得,并且包含格式化字符(|, +, -)。mysqlreport 認為這樣的文件"狀態名 數值"格式的,狀態包含字符和下劃線(A-Z 和 _),數值則是非負整數。在狀態名和數值之間的任何內容都會被忽略。mysqlreport 也需要以下MySQL服務器系統變量:version, table_cache, max_connections, key_buffer_size, query_cache_size, thread_cache_size。INFILE 的格式也可以是 "名字 = 數值"這樣的,名字可以使是上面提到的各種變量名,數值是非負整數,可能后面帶有M或者其他單位(根據版本不同而定)。例如,想要指定 18M 的 key_buffer_size:key_buffer_size = 18M。或者,256 個 table_cache:table_cache = 256。M 指兆字節,而非百萬。因此 18M 是 18,874,368,而非 18,000,000。如果這些服務器變量沒有指定,則使用默認以下默認值:0.0.0, 64, 100, 8M, 0, 0,就可能會讓報告結果看起來很奇怪。
注意:MySQL 服務器版本在 5.1.3 或更新時,盡管系統變量 table_cache 改成了 table_open_cache,但是讀取本地文件時仍采用 table_cache。
--outfile FILE???????? 在屏幕顯示完報告結果后,將結果寫入文件中。mysqlreport 的內部機制總是先將結果寫入臨時文件中。然后將該臨時文件里的內容打印到屏幕上。然后,如果指定了 --outfile 選項,則將臨時文件拷貝成 OUTFILE。如果指定選項 --email,則會刪除臨時文件。
--email ADDRESS???????? 在屏幕顯示完結果后,將結果發送到郵件地址 ADDRESS 中去。欲該選項,需要在 /usr/sbin/ 目錄下有 sendmail 程序,因此無法在 windows 平臺下使用。/usr/sbin/sendmail 可以符號鏈接到 qmail,或者任何其他能模擬 sendmail -t 方式的 MTA 程序。郵件來源是:mysqlreport,主題是:MySQL status report on HOST,HOST 是 mysqlreport
所在的主機名,可能是讀取到的 --host 值,默認是 localhost。
--flush-status???????? 顯示完報告后,執行 "FLUSH STATUS;" 語句。如果沒有權限,則 DBD::mysql 會顯示返回值。
--relative (-r) X???????? mysqlreport 通常情況下報告的是自從 MySQL 服務器啟動以來的狀態信息。--relative 選項則是令 mysqlreport 產生一份自從上次報告以來的相關報告。
如果 --relative X 的 X 值是一個整數,則 mysqlreport 會在隔 X 秒后再次產生一份 MySQL 服務器的狀態報告。產生報告的次數是由 --report-count 選項來控制的。默認是產生 1 份相關的報告。例如,指定 --relative 的值為 60,則會產生 2 份報告:第一份會馬上生成,第二份會在 60 秒后再次生成。第二份報告中的數值會和前面的那份相關。例如,前面那份中總共有 10.00k 次查詢,在這 60 秒的間隔時間里接受了新的 1.00k 次查詢,則第二份的報告中的總查詢次數是 1.00k 而非 11.00k 次。
?
如果 --relative 選項的值也可以是本地文件(類似 --infile 選項的用法),那么 mysqlreport 會按照參數值中文件的順序來依次產生狀態報告。因此,根據這些文件產生的時間來指定選項的值非常重要:較早產生的文件放在參數的前面。第一個文件中必須有手工添加的系統變量,例如:key_buffer_size、table_cache 等。每個文件中可以有多組 "SHOW STATUS" 的結果。注意:通過 "mysqladmin -r -i N extended" 產生的狀態文件無法使用,因為 mysqladmin 的 -r 參數已經令其產生了具有相對性的狀態值了。
?
由于 mysqlreport 首先會把狀態報告寫到臨時文件中,如果 --relative 的值是 整數(而非 本地文件)時,mysqlreport 會顯示它把文件寫到哪了。那么就可以直接通過查看這些文件內容來觀察服務器的狀況了。
--report-count (-c) N???????? 生成 N 份相關的報告。本選項只有在同時啟用 --relative 選項后才有效。mysqlreport 會自動產生 N+1 份報告:第一份基本報告,以及后面的 N 份相關報告。
--detach???????? 若指定本選項,則 mysqlreport 會派生出進程來,不只是在屏幕顯示結果,還會轉入后臺繼續運行。派生新進程后,mysqlreport 會報告它把結果寫入哪個臨時文件了。本選項還可以指定 --outfile 或 --email 的一個。如果沒有指定 --outfile 或 --email 的值,則產生的臨時文件會被刪除,因為 mysqlreport 派生出新進程后,無法再將結果打印到終端屏幕上了。本選項如果和 --relative 一起使用的話就更有意義了,這樣 mysqlreport 就能定時報告信息,而無需人工登錄等方式在中斷執行了。使用如下的命令,就能讓 mysqlrepot 隔一個小時再次產生一次報告,并將結果發送到自己的信箱中去:
mysqlreport -r 3600 -detach -email host@domain.com
一個小時候后,mysqlreport 通過email發送報告,刪除臨時文件,并且干凈地終止。
--debug???????? 顯示調試信息。
--dtq???????? (Questions 報告的 Total 部分中)顯示所有的查詢分布報告。這些查詢主要包括以下四部分:DMS (見下面)、COM_ (見下面)、COM_QUIT(見 COM_QUIT and Questions)、以及其他未知。每部分根據其總數倒序顯示。
--dms???????? (Questions 報告的 DMS 部分中)顯示所有的數據維護語句(DMS)報告。DMS是下面文檔 13.2. Data Manipulation Statements 中提到的那些(當前主要有:SELECT, INSERT, REPLACE, UPDATE, and DELETE)。每個 DMS 根據其總數倒序顯示。
--com N???????? (Questions 報告之后)以降序顯示最多 N 個 非DMS Com_ 狀態值。如果沒有指定 N 的值,則默認是 3。所謂的非DMS Com_ 狀態值,包括:Com_change_db、Com_show_tables、Com_rollback 等。
--sas???????? (Questions 報告之后),顯示所有的 Select_ 和 Sort_ 報告。詳情請看 MySQL Select and Sort Status Variables。
--qcache???????? 如果打開查詢緩存的話,則顯示查詢緩存狀態報告。
--tab???????? (Create Temp 報告之后)顯示 線程、放棄的、流量 等狀態報告。從 mysqlreport v2.3 開始,線程狀態是從 Threads_ 狀態值讀取。
--innodb???????? 顯示 InnoDB 狀態報告,包括MySQL 5.0.2以后才支持的InnoDB 緩沖池,以及5.0.3以后才支持的InnoDB鎖狀態報告。
--innodb-only???????? 只顯示 InnoDB 報告;不顯示其他報告。
--dpr???????? 顯示 InnoDB 數據,頁,行報告。
--all???????? 如果可能,則顯示所有的狀態報告。一些報告,比如查詢緩存、InnoDB等需要特定版本的MySQL或者其他特性才能支持。例如,盡管服務器支持查詢緩存,但是它被禁用了,則不管是否指定了 --qcache 或者 --all,都不會顯示查詢緩存的報告。
MySQL?效能監控工具--mysqlreport?
管理?MySQL?最讓人困擾的就是如何有效的掌握?MySQL?的健康狀況,因為?MySQL?雖然有提供許多系統變量值供您參考,但這些零散的數據若要手動搜集與過濾將會是一件十分沒有效率的事情(除非您寫?Scripts?去分析)。而接下來要介紹的這套?"工具"?其實是由?hackmysql.com?的站長所撰寫的?Perl?Scritps,旨在協助?MySQL?DBA?搜集與分析?MySQL?的運作狀況。
官方網站:?http://hackmysql.com/
軟件下載:?http://hackmysql.com/mysqlreport
這份文件有很大部份是參考?Daniel?Nichter?的?mysqlreport?Guide(http://hackmysql.com/mysqlreportguide),但不完全是翻譯,里面加入了一些我覺得可能會對讀者有幫助的數據,并刪除了部份我認為會對讀者產生混淆的信息。小弟的功力不足,也許會有所錯誤,若是您發現我有地方寫錯了也請您不吝指正,謝謝。
接下來本文開始:
mysqlreport?可將重要的?MySQL?系統信息整理為具有較高可讀性的報表,使你更容易閱讀與深入理解目前?MySQL?的實際運作狀況。除了手動執行?SHOW?STATUS?指令并以人眼去過濾與判斷目前的系統狀態以外,mysqlreport?大概是較好(八成也是唯一)的替代方案。
目前的?mysqlreport?版本可以產生大量、具有完善信息的報表,其報表完整的覆蓋了實務上所有重要的?MySQL?系統信息,也可以產生只具有最重要信息的較精簡報表。完整的報表包含了?14?種不同面向,超過?121?行的完整信息;精簡的報表包含了?6?種不同面向,總計?29?行的最重要信息。
此文件可教導您如何解讀?mysqlreport?所產生出來的各項信息。如此一來,當您在閱讀?mysqlreport?所產生出來的報表時,您才可以回答最重要的問題:『MySQL?Server?目前的運作狀況究竟如何?』
為了讓您有較深入的理解,此文件將從報表的第一行開始逐項的解釋,當您閱讀完此文件后,您應該具有完整的知識可以將?mysqlreport?布署在任何?Server?上,并且有效的掌握?MySQL?Server?的運作實況。
在開始之前,這里有一份范例報表,我們將以此份報表為藍本開始進行教學。
(建議您將此報表打印出來和內文對照看,這樣子會比較容易理解文章內容)
PHP?語法:
???2?
???3?__?Key?_________________________________________________________________?
???4?Buffer?used???380.00k?of?512.00M??%Used:???0.07?
???5???Current??????59.32M????????????%Usage:??11.59?
???6?Write?ratio??????0.93?
???7?Read?ratio???????0.00?
???8??
???9?__?Questions?___________________________________________________________?
??10?Total??????????98.06k???47.46/s?
??11???DMS??????????81.23k???39.32/s??%Total:??82.84?
??12???QC?Hits??????16.58k????8.02/s???????????16.91?
??13???COM_QUIT????????200????0.10/s????????????0.20?
??14???Com_????????????131????0.06/s????????????0.13?
??15???-Unknown?????????82????0.04/s????????????0.08?
??16?Slow????????????????0????0.00/s????????????0.00??%DMS:???0.00?
??17?DMS????????????81.23k???39.32/s???????????82.84?
??18???SELECT???????64.44k???31.19/s???????????65.72?????????79.33?
??19???INSERT???????16.75k????8.11/s???????????17.08?????????20.61?
??20???UPDATE???????????41????0.02/s????????????0.04??????????0.05?
??21???REPLACE???????????0????0.00/s????????????0.00??????????0.00?
??22???DELETE????????????0????0.00/s????????????0.00??????????0.00?
??23?Com_??????????????131????0.06/s????????????0.13?
??24???change_db???????119????0.06/s????????????0.12?
??25???show_fields???????9????0.00/s????????????0.01?
??26???show_status???????2????0.00/s????????????0.00?
??27??
??28?__?SELECT?and?Sort?_____________________________________________________?
??29?Scan???????????????38????0.02/s?%SELECT:???0.06?
??30?Range??????????????14????0.01/s????????????0.02?
??31?Full?join???????????3????0.00/s????????????0.00?
??32?Range?check?????????0????0.00/s????????????0.00?
??33?Full?rng?join???????0????0.00/s????????????0.00?
??34?Sort?scan??????????14????0.01/s?
??35?Sort?range?????????26????0.01/s?
??36?Sort?mrg?pass???????0????0.00/s?
??37?
??38?__?Query?Cache?_________________________________________________________?
??39?Memory?usage???17.81M?of??32.00M??%Used:??55.66?
??40?Block?Fragmnt??13.05%?
??41?Hits???????????16.58k????8.02/s?
??42?Inserts????????48.50k???23.48/s?
??43?Prunes?????????33.46k???16.20/s?
??44?Insrt:Prune????1.45:1????7.28/s?
??45?Hit:Insert?????0.34:1?
??46?
??47?__?Table?Locks?_________________________________________________________?
??48?Waited??????????1.01k????0.49/s??%Total:???1.24?
??49?Immediate??????80.04k???38.74/s?
??50?
??51?__?Tables?______________________________________________________________?
??52?Open??????????????107?of?1024????%Cache:??10.45?
??53?Opened????????????118????0.06/s?
??54?
??55?__?Connections?_________________________________________________________?
??56?Max?used???????????77?of??600??????%Max:??12.83?
??57?Total?????????????202????0.10/s?
??58?
??59?__?Created?Temp?________________________________________________________?
??60?Disk?table?????????10????0.00/s?
??61?Table??????????????26????0.01/s?
??62?File????????????????3????0.00/s?
??63?
??64?__?Threads?_____________________________________________________________?
??65?Running????????????55?of???77?
??66?Cache???????????????0??????????????%Hit:????0.5?
??67?Created???????????201????0.10/s?
??68?Slow????????????????0????0.00/s?
??69?
??70?__?Aborted?_____________________________________________________________?
??71?Clients?????????????0????0.00/s?
??72?Connects????????????8????0.00/s?
??73?
??74?__?Bytes?_______________________________________________________________?
??75?Sent???????????38.46M??18.62k/s?
??76?Received????????7.98M???3.86k/s??
Report?Header:?Line?1?
報表的第一行包含了三樣不同的信息:MySQL?Server?的版本、自上次啟動后已經過多少時間、目前?Server?的日期與時間。有些人會定時讓系統自動產生報表(eg.?cron)然后用程序去分析進行分析,此時表頭將可用來協助您辨識出不同時間點的報表。對于那些租用或使用虛擬主機的管理者,表頭可以協助您了解自己所需面對的是什么樣的?Server。MySQL?Server?版本可以指出該?Server?有提供或沒有提供那些功能,而它的?Uptime?則表示該報表具有多大的代表性。Uptime?是重要的指標,可讓您了解此份報表所包含的信息是否可能有偏誤,一般來說?Uptime?最少要有一小時會比較適當,甚至光是一小時其實也還不夠。例如您的?Server?可能已執行了六個小時,但此六小時皆是在使用率最低的午夜,此時產生出的報表就很不具有代表性。最理想的情況下,你會希望?MySQL?Server?至少已經執行了一整天,這樣子一來你就可以確定報表中的信息已包含了?Server?負載的高峰與低峰期,而不是只包含其中之一。在范例報表中?Server?只執行了?34?分鐘,因此該報表的代表性是不足的,但因為這只是用來做范例,也就沒什么關系。
Key?Report:?Lines?3?-?7?
第一個主要報告區塊就是?Key?Report,因為?Key(Indexes,?索引)是所有信息中最重要的一項。雖然此報表無法告知您?Server?是否有善用?Index,但它可以告訴您?Server?對于?Shared?Key?Buffer?的使用狀態。請注意,這里所指的?Key?Buffer?是指?MyISAM?Storage?Engine?所使用的?Shared?Key?Buffer,InnoDB?所使用的?Key?Buffer?并不包含在內。
MySQL?Server?支持許多種不同類型的數據表(比較正式的說法是?Storage?Engine),你可以將它們想象為各種不同的數據結構,而不同的?Storage?Engine?各有其優缺點。其中?MySQL?Server?預設是使用?MyISAM?Storage?Engine。
MySQL?Server?的?Buffer?大略可分為二種:
1.?Global?Buffer:由所有?Client?所共享的?Buffer?
key_buffer
innodb_buffer_pool
innodb_log_buffer
innodb_additional_mem_pool
net_buffer?...等等2.?Thread?Buffer:個別的?Connection?所需占用的?Buffer?
例如:
sort_buffer
myisam_sort_buffer
read_buffer
join_buffer
read_rnd_buffer?...等等計算?Server?至少需使用的總內存數量的方式為:
min_memory_needed?=?global_buffer?+?(thread_buffers?*?max_connection)
關于?MySQL?的?Cache?機制有一點需要特別注意,各位應該都知道?MyISAM?Storage?Engine?將每個?table?分成三個檔案儲存在硬盤之中,例如若您有一個數據表的名稱為?example,那么您就會在硬盤上發現?example.FRM,?example.MYD,?example.MYI?等三個檔案。這三個檔案所儲存的數據如下:?
FRM:?儲存這個數據表的結構
MYD:?Row?Data,也就是你存在?example?數據表里的數據
MYI:?此數據表的索引接下來是重點:
當?MySQL?要?Cache?某個資料表時,請問?MySQL?會?Cache?哪些資料?
答案是:
MySQL?只會?Cache?索引,也就是?*.MYI?檔案,而?Row?Data(*.MYD)?則是交由操作系統來負責?Cache。
接下來我們再回到?Key?Buffer,有個很重要的問題我們一直沒有回答,就是『到底?Key?Buffer?要設定多少才夠呢?』。如前所述,MySQL?只會?Cache?索引(*.MYI),因此您只要將數據庫中所有的?MYI?檔案加總起來,你就會知道大概要設為多少。
Buffer?used:?Line?4?
身為?MySQL?的管理者您通常會問的第一個問題是:『Server?到底用掉了多少?key?buffer?』。如果您發現?MySQL?只使用了一小部份的?Key?Buffer,這并不是什么需要注意的問題,因為?MySQL?只會在需要的時候才實際分配與使用?System?RAM。也就是說,當你設定?MySQL?可使用?512MB?的?RAM?時,并不代表?MySQL?啟動的時候將占用?512MB?的?RAM(只有在?MySQL?認為需要這么做的時候才會)。報表中的第四行(Buffer?used)指出?MySQL?"曾經"?耗用過的最大內存數量,因此目前?"正在使用"?的內存數量有可能少于(甚至大于)這個數字。MySQL?稱此數值為?"High?Water?Mark",但在報表的下一行我們將會看到它并不總是如此。無論如何,從 Buffer?used?我們通常可以看出?key_buffer_size?這個系統變量值是否設定的夠大,如果你的?MySQL?已經使用了?80~90%?以上的?Key?Buffer,你就應該要調高?key_buffer_size。注意,Buffer?used?永遠不會有使用率超過?95%?的情況,因為?MySQL?的官方文件中指出?Share?Key?Buffer?中有部份將會挪用給內部數據結構使用,因此當?Buffer?used?指出?Share?Key?Buffer?的使用率高達?95%?時,其實在實務上等于是已使用了?100%?的?Share?Key?Buffer。在這個例子中?Server?只使用了?380KB(0.07%)?的?Share?Key?Buffer,看到這里也許您會判斷?Server?的?Share?Key?Buffer?是十分充足的,但請勿太早下定論,我們必須要接著考慮報表中的下一行才能做出客觀的判斷......。
Current:?Line?5?
mysqlreport?使用?Key_blocks_unused?這個系統變量來決定目前?MySQL?"正在使用"?的?Share?Key?Buffer?大小,只有在?MySQL?Server?4.1.2?以上的版本才會有這個功能。如果報表中的上一行(Buffer?used)真的有如?MySQL?官方文件中所說的是?"High?Water?Mark",那么?Current?所載明的數值應該永遠會小于或等于它。但在接下來的例子中我們將會看到,事情并不總是如此。目前這臺?Server?已經使用了大約?60MB(12%)?的?Share?Key?Buffer,這是一個好現象因為它代表了你的?Share?Key?Buffer?仍然十分充足。Current?與?Buffer?used?合在一起看即可提供一個很有用的指標,告訴您目前的?key_buffer_size?是否充足。
設定?key_buffer_size?的方式也很簡單,只要直接修改?MySQL?的設定檔然后重新啟動?Server?即可。例如若要將?Key?Buffer?設定為?2000MB,則只要在?/etc/my.cnf?中加上:
[mysqld]
key_buffer_size=2000M
Write?ratio:?Line?6?
索引(Indexes,?Keys)主要是在內存內(RAM-Based)進行操作的,索引之所以如此有用有部份原因就歸功于它們主要是在?RAM?里面運作,因此擁有極高的存取效能,不像儲存在硬盤中的數據存取速度非常慢。然而,不可否認的是?MySQL?終究還是必須從硬盤中將索引讀入?RAM?或是將儲存在?RAM?中的索引寫回硬盤之中。Write?ratio?標示著?MySQL?將索引寫入硬盤與?MySQL?將索引寫入?RAM?的比值(Write?Ratio?=?MySQL?將索引寫入硬盤的次數?/?MySQL?將索引寫入?RAM?的次數)。具有接近于?1?的?Write?Ratio?并不是一件很罕見的事,就像?MySQL?官方手冊中所說的,如果你的?MySQL?最主要的活動是?Update、Insert?等等,那么?Write?Ratio?將會很接近于?1。Write?Ratio?若大于?1?表示?MySQL?將索引寫入硬盤的次數大于將索引寫入?RAM?的次數,很少有?MySQL?Server?的?Write?Ratio?會大于?1,絕大部份都應該會小于?1,即便是負載非常重的?Server。
Read?ratio:?Line?7?
Read?Ratio?比?Write?Ratio?來得重要一些,它標示了?MySQL?從硬盤讀取索引與從?RAM?讀取索引的比值(Read?Ratio?=?MySQL?從硬盤讀取索引的次數?/?MySQL?從?RAM?讀取索引的次數)。Read?Ratio?的值應該要是?0.00?或?0.01,若大于這個值則表示?Server?有問題需要進一步的調查,通常此問題的成因是?Share?Key?Buffer?設得太小造成?MySQL?需要不斷地從硬盤中讀取所需要的索引信息,而這個動作是十分沒有效率的并且完全抵消了使用索引可以帶來的好處。在?Server?剛啟動的頭一個小時?Read?Ratio?很常會出現大于?0.01?的數值,但?Server?執行過一陣子后它應該(也必須)降低至?0.01?或是?0.00。
Questions?Report:?Lines?9?-?26?
第二個主要的報表區塊,Questions,是第二重要的信息,因為它可以告訴你?MySQL?到底都在忙些什么事情。Questions?包含了?SQL?queries?以及?MySQL?protocol?communications。大部份的人都只在意?Server?每秒可以處理多少查詢(Queries?Per?Second,?QPS),但若以整個?Server?的觀點來考慮,QPS?其實是非常不精確的數值,它無法有效的告訴您?Server?的整體運作狀況。而?Questions?則提供了較完整的信息,讓您一窺?Server?的全貌。
Total:?Line?10?
第一個字段單純的記載?MySQL?總共響應過多少查詢,第二個字段則記錄響應的頻率(QPS),當大部份的人說『我的?Server?平均每秒處理?XXX?個查詢』時,他們指的其實就是第二個字段所記錄的響應頻率。此時你應該要反問他們『在那?XXX?個查詢之中,MySQL?到底做了哪些事情?』,接下來?mysqlreport?將可以協助您回答此問題......。
Distribution?of?Total?Queries?(DTQ):?Lines?11?-?15?
所有的?Questions?可以大致區分為五個不同的類別:
1.Data?Manipulation?Statements?(DMS)
2.query?cache?hits?(QC?Hits)
3.COM_QUIT
4.all?other?Com_?commands
5.Unknown
這五個類別將會展示在?Lines?11?至?15,但它們的順序是會改變的。mysqlreport?預設是以查詢的總數(第一個字段)來排序,次數越多排得越上面,讓您可以快速的分辨出?MySQL?大部份時間都在忙些什么東西。理想的情況下,你會希望?MySQL?把大部份的時間都花在?DMS?與?QC?Hits?這兩個類別,因為這兩個類別才是真正在?"完成正事"?的類別。COM_QUIT、Com_、與?Unknown?也有其存在的必要,但它們應該只占了其中的一小部份。在繼續深入介紹之前,也許你會好奇第三個字段是做什么用的,它代表了該分類(例如?DMS)占全部?Queries?的百分比;若是在子分類(例如?Select)中,則表示該子分類占所屬分類(例如?DMS)的百分比。在此范例中?DMS?占了所有?Queries?的?82.84%,這是一個很好的現象。
Data?manipulation?statements(DMS)?包含了:ELECT,?INSERT,?REPLACE,?UPDATE,?與?DELETE(技術上來說,其實不只這幾個類別但?mysqlreport?只會用到這幾類)。基本上,你可以將?DMS?想成是?MySQL?真正有在做些?"有用的事"?的情況,因此你會希望?DMS?是?MySQL?最忙著處理的事情。
QC?Hits?是?MySQL?不需要實際執行?Query?而只要直接從?Query?Cache?中即可找到所需數據的次數。擁有高比例的?QC?Hits?是讓人夢寐以求的事,因為從?Query?Cache?直接存取所需要的數據是十分快速且有效率的。然而大部份的?MySQL?Server?因為各種原因,而無法具有非常有效率的?Query?Cache。在本范例中?QC?Hits?占了所有?Questions?的?16.91%,這是非常好的情況。然而,千萬不要被這個數值給誤導了,在報表中的?38?至?45?行(Query?Cache?Report)將會告訴您完全不同的狀況。這是一個很好的范例,展示了?mysqlreport?可以做為深入、相互參照與比對的分析工具。當?QC?Hits?看來似乎十分完美時,這個?Server?的?Qeury?Cache?Report?卻可以明確的告訴您其實事情沒有表面上看起來的那樣完美,我們在稍后會在回到這個問題。
COM_QUIT?算是比較不重要的類別,若您不是真的很有興趣其實您大可忽略這個類別的內容。
COM_?這個類別代表著所有?MySQL?所執行過的指令,通常與?MySQL?protocol?相關。在正常的情況下,你會希望這個類別所占的比例越低越好,因為當這個數值很高的時候就表示?MySQL?正忙碌于無關緊要的事情上。若這個數值很高通常代表?MySQL?正遭遇到某些很奇怪的問題,當我們深入討論?COM_?的子類別的時候,我們會在回來探討這個問題。
Unknown?是推論出來的類別,在理想的狀況下,之前所述的四個分類加總起來應該要等于?Questions?總數,但它們通常不會剛好等于。這是因為有些?Questions?MySQL?在處理時會增加?Total?Questions?的計數器,但卻沒有相對應的系統變量用來記錄所執行過的?Questions。在不同的?Server?上這個數值的變異很大,在有些?Server?上這個數值非常的高,在有些?Server?上則非常的低,但在大部份的情況下它應該要維持在很低的水平才是。如果這個數值非常的高,可能代表?MySQL?Server?有什么地方出了問題。
Slow:?Line?16?
第?16?行非常的重要:它記錄了?MySQL?總共執行了多少次?Slow?Query。Slow?Query?就是指執行所需時間超過某個時間區間的?Query,例如執行超過?10?秒的?Query。用來判定是否為?Slow?Query?的時間區間是可以透過?long_query_time?這個系統變量來設定的,MySQL?預設?long_query_time?為?10?秒,但通常我們會將它設定為?5?秒。在最理想的情況下,我們會希望看到這個數值等于零,但通常這數值不會是零。一般來說?Slow?Query?占?Total?Questions?的比例應該要低于?0.05,Slow?Query?的次數(第一個字段)本身不是很重要,真正需要注意的是?Slow?Query?占?Total?Questions?的比例,若這比例偏高就代表?Server?有些問題需要解決。第四個字段中的『%DMS:?』表示?Slow?Query?在所有?DMS?中所占的比例。
DMS:?Lines?17?-?22?
DMS?的子分類項目可以告訴我們,這臺?MySQL?Server?是屬于哪一個類型的?MySQL?Server,例如它是著重在?SELECT?操作或是?INSERT?操作,大部份的?MySQL?Server?都是著重在?SELECT?操作。知道某臺?Server?是屬于哪一個類型的?MySQL?Server?有助于我們思考報表中的其它信息,例如一臺著重在?SELECT?操作的?MySQL?Server?的?Write?Ratio?應該會非常的接近?1,并有著較高的?Lock?時間。同時它也隱含了一個意義,就是也許你可以考慮使用?InnoDB?Storage?Engine,因為?MySQL?預設采用的?MyISAM?Storage?Engine?所提供的?Lock?層級只有?Table?Lock(只能針對整個數據表鎖定),而?InnoDB?則提供?Row?Lock?層級的鎖定機制(可只針對特定的?ROW?進行鎖定,減少等待時間)。若是著重在?SELECT?操作的?Server,它的?Read?Ratio?應該會接近于零,并有著非常低的?Table?Lock?時間。
在范例中的?Server?是屬于著重在?SELECT?操作的?Server:65.72%?的?Questions?是?SELECT(第三個字段)、79.33%?的?DMS?Questions?是?SELECT(第四個字段)。很明顯的,這是臺著重在?SELECT?操作的?Server,知道了此項事實之后,我們才有辦法對其進行最佳化。
Com_:?Lines?23?-?26?
這個子分類只有在它的值偏高的時候才需要注意,因為過高的值表示?MySQL?正在忙著處理?"程序方面的東西",而不是響應使用者的查詢。對大部份的?Server?來說這里應該都不會出現偏高的數值,但您最好還是定期的檢查一下。
SELECT?and?Sort?Report:?Lines?28?-?36?
大致上來說,你只要注意第?29?行與第?31?行:Scan?與?Full?Join。Scan?指的是有多少?SELECT?statements?造成?MySQL?需要進行?Full?Table?Scan。Full?Join?的意思與?Scan?差不多,但它是適用在多個?Tables?相互?Join?在一起的情況。這二種情況的執行效能都非常的差,因此原則上你會希望這兩個數值越低越好。但這也不是絕對的,仍然要考慮實際的情況,例如雖然?Server?有很高比例的?Scan,但若這些?Scan?都是針對一些只有幾十筆數據的?table,那么相對而言它依然是十分有效率的;但反之,若這些?Scan?是針對具有上百萬筆數據的?table,那么就會嚴重影響系統效能。
Query?Cache?Report:?Lines?38?-?45?
Query?Cache?Report?只有在?MySQL?有支持?Query?Cache,以及?Query?Cache?功能有開啟的情況下才會有這段信息出現。
Memory?usage:?Line?39?
此項目指出?Query?Cache?的使用狀況,若系統已達到?Query?Cache?的上限則會連帶影響到?Prunes?Value,因為當配給的?Memory?不足時,MySQL?必須不斷地消除?RAM?中較不常使用的數據以挪出空間擺放新的數據。
Block?Fragmnt:?Line?40?
這個數值越高表示?Query?Cache?的?Fragment?狀況越嚴重,通常它會界于?10%~20%?之間。在此范例中?Block?Fragmnt?為?13.05%,這是可接受的情況,當然你也可以調整?query_cache_min_res_unit?的值來降低?Block?Fragmnt。
Hits,?Inserts,?Prunes:?Lines?41?-?43?
Hits?是這三個數值中最重要的一項,因為它指出有多少?SELECT?statements?是可直接從?Query?Cache?里面取得所需的信息,此數值越高就越好。Inserts?和?Prunes?最好是從第?44?行的比值來觀察比較容易理解。雖然?Prunes?的值偏高可能代表著?Query?Cache?設得不夠大,但并不一定是如此。在本例中只有?55%?的?Query?Cache?被使用,有著相對而言算低的?fragmentation?值,但?Prunes?值偏高,Prunes?的值(16/s)是?QC?Hits?的兩倍。你可以想象這臺?Server?的?Query?Cache?是一顆蘋果樹,它的樹枝被剪去的速度比你采收蘋果的速度還快。
Insrt:Prune?and?Hit:Insert?Ratios:?Lines?44?-?45?
第?44?行中的?Insert?與?Prune?的比值可顯示?Query?Cache?的揮發性。在一個高度穩定的?Query?Cache?中,Insrt?的值應該要高于?Prune?的值;反之,在一個揮發性較高(較不穩定)的?Query?Cache?中,這個比值將會是?1:1?或是偏重在?Prune?那方,這表示?Query?Cache?中的數據有可能在使用到之前就已經被清除了。我們會希望擁有一個穩定的?Query?Cache,因為穩定的?Query?Cache?表示那些被?Cache?在?Query?Cache?中的資料會常被用到。高揮發性(較不穩定)的?Query?Cache?代表兩件事情:第一,Query?Cache?設得太小,需要加大。第二,MySQL?正試圖要?cache?所有的東西,甚至是那些其實并不需要?cache?的數據。若是第一種狀況,只要單純的加大?Query?Cache?即可。若是第二種情況,可能是?MySQL?試圖要去?cache?所有可以?cache?的數據,你可以使用?SQL_NO_CACHE?來明確的告訴?MySQL?什么資料是你不想要?cache?的。
Hit?與?Insert?的比值代表著?Query?Cache?的有效性,理想的情況是我們新增了一些?Qeury?到?Query?Cache?中,然后希望得到許多?Hits。因此若是這個?Query?Cache?是有效率的,那么該比值應該要偏重在左方。若比值是偏重在?Insert?那方,那么這個?Query?Cache?的揮發性就太高了。考慮以下這個比值,若?Hit:Insert?為?1:1,那就表示?Query?Cache?中的數據只使用了一次就被清除掉了,換句話說,我們放進去的數據比我們從里面拿出來的數據還多,這樣一來就失去了使用?Query?Cache?的意義。回想我們前面所提過的,雖然在本范例中?QC?Hit?在全部的?Questions?中占了很高的比例,但實際上我們可以發現?QC?的有效性其實是很低的(Hit:Insert?的比值偏重在?Insert?那方)。若造成這個現象的原因是?MySQL?正試圖?cache?所有的東西,那么將?Cache?模式改為?DEMAND?或許可以解決此問題。
Table?Locks?Report:?Lines?47?-?49?
這個部份包含了兩項信息:第一項是?Waited,代表?MySQL?需要等待以取得?table?lock?的次數。第二項是?Immediate,表示?MySQL?不需要等待即可立刻取得?table?lock?的次數。對數據庫來說『等待』幾乎可以肯定是一件很不好的事情,因此?Waited?的值應該要越小越好。最具有代表性的是第三個字段(Waited?占所有?table?lock?的百分比),這個數值應該要小于?10%,大于這個值就表示?table/query?的索引設計不良或是有過多的?Slow?Query。?
Tables?Report:?Lines?51?-?53?
Tables?Report?同樣包含了二項信息:第一是?Open,顯示目前正開啟的?table?數量、總共可開啟的最大數量,以及?Table?Cache?的使用狀況。第二是?Opend,表示截至目前為止?MySQL?總共開啟過的?Table?數量,以及除上?Uptime?后的比值。這里有兩件事值得注意:首先是?Table?Cache?的使用狀況,100%?的?Table?Cache?使用率并不是一件壞事但你可以試著調大?Table?Cache?以增進效能。第二是?MySQL?開啟?Table?的平均速率,若這個值很高則表示您的?table_cache?設得太小了,需要調大一些。一般來說,MySQL?開啟?Table?的平均速率最好是小于?1/s。但大于這個數值也不一定就是壞事,有些調校良好且運作的十分有效率的?MySQL?Server?其值為?7/s?并使用了?100%?的?Table?Cache。
Connections?Report:?Lines?55?-?57?
Connections?Report?所代表的意義與?Tables?Report?相似,請各位以此類推。比較需要注意的是:若你發現?Connections?的使用率接近?100%,也許你會想調大?max_connections?的值以允許?MySQL?的?Client?建立更多聯機。然而,這通常是一種錯誤。我們常常可以發現很多網絡上的數據會教我們要調大?max_connections,但卻從來沒有給一個明確的理由。事實上,max_connections?的默認值(100),就算是對于負載十分沉重但有良好調校過的?Server?都已十分足夠。MySQL?對于單一聯機的數據處理通常只需要零點幾秒的時間即可完成,就算是最大只能使用?100?個聯機也夠讓你用上很長一段時間。若是您的?Server?有著非常高的最大聯機數(max?connections)或是單一聯機需要很長時間才可完成,那么問題八成不是?max_connections?的值不夠大而是在別的地方,例如?slow?queries、索引設計不良、甚至是過于緩慢的?DNS?解析。在您將?max_connections?的值調到?100?以上之前,您應該要先確定真的是因為?Server?過于忙碌而需要調高此數值,而不是其它地方出了問題。每秒平均聯機數有可能會很高,事實上,若這個值很高而且?Server?的運作十分順暢,那么這通常會是一個好現象,無需擔心。大部份?Server?的每秒平均聯機數應該都會低于?5/s。
Created?Temp?Report:?Lines?59?-?62?
MySQL?可以建立暫時性的數據表,它可建立在硬盤中、檔案里、或是?RAM?之中,而?Created?Temp?Report?則提供了相關的數據供您參考。這些數據大多是相對而言,沒有一定的標準,但將暫時性的數據表建立在硬盤中是十分沒有效率的,因此?Disk?table?的值最好是三者中最小的一個。當暫時性的數據表被建立在硬盤中,表示此數據表沒有辦法被放進?RAM?里面(因為?tmp_table_size?的值設得不夠大)。
Threads,?Aborted,?Bytes?Reports:?Lines?64?-?76?
這幾個部份大多沒什么好解釋的,只有一個項目值得特別說明:第?66?行的最后一個字段(%Hit)。每一個連接到?MySQL?的聯機都是由不同的?Thread?來處理,當?MySQL?啟動時會預先建立一些?Threads?并保留在?Thread?Cache?中,如此一來?MySQL?就不用一直忙著建立與刪除?Threads。但當每秒最大聯機數大于?MySQL?的?Thread?Cache?時,MySQL?就會進入?Thread?Thrash?的狀態:它不斷地建立新的?Threads?以滿足不斷增加的聯機的需求。當?Thread?Thrash?發生時,%Hit?的數值就會降低。在本范例中?%Hit?的值為?0.05%,這是非常不好的,因為它表示幾乎每一個新進來的聯機都會造成?MySQL?建立新的?Thread。我們可以看到在此范例中造成此現象的原兇就在第?66?行的第一個字段,我們可以發現?Thread?Cache?的值為?0,因此?thread_cache_size?的值需要調大。
話說回來,究竟?%Hit?接近于零真的有什么關系嗎?Jeremy?Zawondy?曾在部落格上說到:Thread?caching?并不是我們最需要關心的問題,但當你解決了所有其它更嚴重的問題之后,它就會是最嚴重的問題。(hread?caching?really?wasn't?the?worst?of?our?problems.?But?it?became?the?worst?after?we?had?fixed?all?the?bigger?ones.)
?http://www.coffeephp.cn/bbs/viewthread.php?tid=3
http://imysql.cn/node/319
http://www.gingili.cn/article/2007/1025/article_880.html
?