捕獲診斷數(shù)據(jù)( )
創(chuàng)新互聯(lián)是專業(yè)的南京網(wǎng)站建設(shè)公司,南京接單;提供做網(wǎng)站、成都網(wǎng)站制作,網(wǎng)頁設(shè)計,網(wǎng)站設(shè)計,建網(wǎng)站,PHP網(wǎng)站建設(shè)等專業(yè)做網(wǎng)站服務(wù);采用PHP框架,可快速的進(jìn)行南京網(wǎng)站開發(fā)網(wǎng)頁制作和功能擴(kuò)展;專業(yè)做搜索引擎喜愛的網(wǎng)站,專業(yè)的做網(wǎng)站團(tuán)隊,希望更多企業(yè)前來合作!
堆棧需要自下而上來看 也就是說 線程當(dāng)前正在執(zhí)行的是pthread_cond_wait 函數(shù) 這是由os_event_wait_low 調(diào)用的 繼續(xù)往下 看起來是線程試圖進(jìn)入到InnoDB 內(nèi)核(srv_conc_enter_innodb) 但被放入了一個內(nèi)部隊列中(os_event_wait_low) 原因應(yīng)該是內(nèi)核中的線程數(shù)已經(jīng)超過innodb_thread_concurrency 的限制 當(dāng)然 要真正地發(fā)揮堆棧跟蹤的價值需要將很多的信息聚合在一起來看 這種技術(shù)是由Domas Mituzas推廣的 他以前是MySQL 的支持工程師 開發(fā)了著名的窮人剖析器 poor man sprofiler 他目前在Facebook 工作 和其他人一起開發(fā)了更多的收集和分析堆棧跟蹤的工具 可以從他的這個網(wǎng)站發(fā)現(xiàn)更多的信息 // poormansprofiler
在Percona Toolkit 中我們也開發(fā)了一個類似的窮人剖析器 叫做pt pmp 這是一個用shell 和awk 腳本編寫的工具 可以將類似的堆棧跟蹤輸出合并到一起 然后通過sort|uniq|sort 將最常見的條目在最前面輸出 下面是一個堆棧跟蹤的完整例子 通過此工具將重要的信息展示了出來 使用了 l 選項(xiàng)指定了堆棧跟蹤不超過 層 以免因太多前面部分相同而后面部分不同的跟蹤信息而導(dǎo)致無法聚合到一起的情況 這樣才能更好地顯示到底在哪里產(chǎn)生了等待
$ pt pmp l stacktraces txt
pthread_cond_wait one_thread_per_connection_end handle_one_connection
start_thread clone
pthread_cond_wait os_event_wait_low srv_conc_enter_innodb
innodb_srv_conc_enter_innodb ha_innodb::index_read
pthread_cond_wait os_event_wait_low sync_array_wait_event mutex_spin_wait
mutex_enter_func
pthread_cond_wait os_event_wait_low os_aio_simulated_handle fil_aio_wait
io_handler_thread
pthread_cond_wait os_event_wait_low srv_conc_enter_innodb
innodb_srv_conc_enter_innodb ha_innodb::general_fetch
pthread_cond_wait os_event_wait_low sync_array_wait_event rw_lock_s_lock_spin
rw_lock_s_lock_func
sigwait signal_hand start_thread clone ??
select os_thread_sleep srv_lock_timeout_and_monitor_thread start_thread clone
select os_thread_sleep srv_error_monitor_thread start_thread clone
select handle_connections_sockets main
read vio_read_buff ::?? my_net_read cli_safe_read
pthread_cond_wait os_event_wait_low sync_array_wait_event rw_lock_x_lock_low
rw_lock_x_lock_func
pthread_cond_wait MYSQL_BIN_LOG::wait_for_update mysql_binlog_send
dispatch_mand do_mand
fsync os_file_fsync os_file_flush fil_flush log_write_up_to
第一行是MySQL 中非常典型的空閑線程的一種特征 所以可以忽略 第二行才是最有意思的地方 看起來大量的線程正在準(zhǔn)備進(jìn)入到InnoDB 內(nèi)核中 但都被阻塞了 從第三行則可以看到許多線程都在等待某些互斥鎖 但具體的是什么鎖不清楚 因?yàn)槎褩8櫢畹膶哟伪唤財嗔?如果需要確切地知道是什么互斥鎖 則需要使用更大的 l 選項(xiàng)重跑一次 一般來說 這個堆棧跟蹤顯示很多線程都在等待進(jìn)入到InnoDB 這是為什么呢?這個工具并不清楚 需要從其他的地方來入手
從前面的堆棧跟蹤和oprofile 報表來看 如果不是MySQL 和InnoDB 源碼方面的專家 這種類型的分析很難進(jìn)行 如果用戶在進(jìn)行此類分析時碰到問題 通常需要求助于這樣的專家才行
在下面的例子中 通過剖析和等待分析都無法發(fā)現(xiàn)服務(wù)器的問題 需要使用另外一種不同的診斷技術(shù)
返回目錄 高性能MySQL
編輯推薦
ASP NET開發(fā)培訓(xùn)視頻教程
數(shù)據(jù)倉庫與數(shù)據(jù)挖掘培訓(xùn)視頻教程
lishixinzhi/Article/program/MySQL/201311/29698
一個診斷案例( )
我們看到了兩種可能性 要么是數(shù)據(jù)庫導(dǎo)致了I/O(如果能找到源頭的話 那么可能就找到了問題的原因) 要么不是數(shù)據(jù)庫導(dǎo)致了所有的I/O 而是其他什么導(dǎo)致的 而系統(tǒng)因?yàn)槿鄙買/O 資源影響了數(shù)據(jù)庫性能 我們也很小心地盡力避免引入另外一個隱式的假設(shè) 磁盤很忙并不一定意味著MySQL 會有問題 要記住 這個服務(wù)器主要的壓力是內(nèi)存讀取 所以也很可能出現(xiàn)磁盤長時間無法響應(yīng)但沒有造成嚴(yán)重問題的現(xiàn)象
如果你一直跟隨我們的推理邏輯 就可以發(fā)現(xiàn)還需要回頭檢查一下另外一個假設(shè) 我們已經(jīng)知道磁盤設(shè)備很忙 因?yàn)槠涞却龝r間很高 對于固態(tài)硬盤來說 其I/O 平均等待時間一般不會超過 / 秒 實(shí)際上 從iostat 的輸出結(jié)果也可以發(fā)現(xiàn)磁盤本身的響應(yīng)還是很快的 但請求在塊設(shè)備隊列中等待很長的時間才能進(jìn)入到磁盤設(shè)備 但要記住 這只是iostat 的輸出結(jié)果 也可能是錯誤的信息
究竟是什么導(dǎo)致了性能低下?
當(dāng)一個資源變得效率低下時 應(yīng)該了解一下為什么會這樣 有如下可能的原因
資源被過度使用 余量已經(jīng)不足以正常工作
資源沒有被正確配置
資源已經(jīng)損壞或者失靈
回到上面的例子中 iostat 的輸出顯示可能是磁盤的工作負(fù)載太大 也可能是配置不正確(在磁盤響應(yīng)很快的情況下 為什么I/O 請求需要排隊這么長時間才能進(jìn)入到磁盤?) 然而 比較系統(tǒng)的需求和現(xiàn)有容量對于確定問題在哪里是很重要的一部分 大量的基準(zhǔn)測試證明這個客戶使用的這種SSD 是無法支撐幾百M(fèi)B/s 的寫操作的 所以 盡管iostat 的結(jié)果表明磁盤的響應(yīng)是正常的 也不一定是完全正確的 在這個案例中 我們沒有辦法證明磁盤的響應(yīng)比iostat 的結(jié)果中所說的要慢 但這種情況還是有可能的 所以這不能改變我們的看法 可能是磁盤被濫用注 或者是錯誤的配置 或者兩者兼而有之 是性能低下的罪魁禍?zhǔn)?/p>
在檢查過所有診斷數(shù)據(jù)之后 接下來的任務(wù)就很明顯了 測量出什么導(dǎo)致了I/O 消耗 不幸的是 客戶當(dāng)前使用的GNU/Linux 版本對此的支持不力 通過一些工作我們可以做一些相對準(zhǔn)確的猜測 但首先還是需要探索一下其他的可能性 我們可以測量有多少I/O來自MySQL 但客戶使用的MySQL 版本較低以致缺乏一些診斷功能 所以也無法提供確切有利的支持
作為替代 基于我們已經(jīng)知道MySQL 如何使用磁盤 我們來觀察MySQL 的I/O 情況 通常來說 MySQL 只會寫數(shù)據(jù) 日志 排序文件和臨時表到磁盤 從前面的狀態(tài)計數(shù)器和其他信息來看 首先可以排除數(shù)據(jù)和日志的寫入問題 那么 只能假設(shè)MySQL 突然寫入大量數(shù)據(jù)到臨時表或者排序文件 如何來觀察這種情況呢?有兩個簡單的方法 一是觀察磁盤的可用空間 二是通過lsof 命令觀察服務(wù)器打開的文件句柄 這兩個方法我們都采用了 結(jié)果也足以滿足我們的需求 下面是問題期間每秒運(yùn)行df–h 的結(jié)果
下面則是lsof 的數(shù)據(jù) 因?yàn)槟承┰蛭覀兠课迕氩攀占淮?我們簡單地將mysqld 在/tmp 中打開的文件大小做了加總 并且把總大小和采樣時的時間戳一起輸出到結(jié)果文件中
$ awk
/mysqld *tmp/ {
total += $ ;
}
/^Sun Mar / total {
printf %s % f MB\n $ total/ / ;
total = ;
} lsof txt
: : MB
: : MB
: : MB
: : MB
: : MB
從這個數(shù)據(jù)可以看出 在問題之初MySQL 大約寫了 GB 的數(shù)據(jù)到臨時表 這和之前在SHOW PROCESSLIST 中有大量的 Copying to tmp table 相吻合 這個證據(jù)表明可能是某些效率低下的查詢風(fēng)暴耗盡了磁盤資源 根據(jù)我們的工作直覺 出現(xiàn)這種情況比較普遍的一個原因是緩存失效 當(dāng)memcached 中所有緩存的條目同時失效 而又有很多應(yīng)用需要同時訪問的時候 就會出現(xiàn)這種情況 我們給開發(fā)人員出示了部分采樣到的查詢 并討論這些查詢的作用 實(shí)際情況是 緩存同時失效就是罪魁禍?zhǔn)祝ㄟ@驗(yàn)證了我們的直覺) 一方面開發(fā)人員在應(yīng)用層面解決緩存失效的問題 另一方面我們也修改了查詢 避免使用磁盤臨時表 這兩個方法的任何一個都可以解決問題 當(dāng)然最好是兩個都實(shí)施
返回目錄 高性能MySQL
編輯推薦
ASP NET開發(fā)培訓(xùn)視頻教程
數(shù)據(jù)倉庫與數(shù)據(jù)挖掘培訓(xùn)視頻教程
lishixinzhi/Article/program/MySQL/201311/29695
測試何種指標(biāo)
在開始執(zhí)行甚至是在設(shè)計基準(zhǔn)測試之前 需要先明確測試的目標(biāo) 測試目標(biāo)決定了選擇什么樣的測試工具和技術(shù) 以獲得精確而有意義的測試結(jié)果 可以將測試目標(biāo)細(xì)化為一系列的問題 比如 這種CPU 是否比另外一種要快? 或 新索引是否比當(dāng)前索引性能更好?
有時候需要用不同的方法測試不同的指標(biāo) 比如 針對延遲(latency)和吞吐量(throughput)就需要采用不同的測試方法
請考慮以下指標(biāo) 看看如何滿足測試的需求
吞吐量
吞吐量指的是單位時間內(nèi)的事務(wù)處理數(shù) 這一直是經(jīng)典的數(shù)據(jù)庫應(yīng)用測試指標(biāo) 一些標(biāo)準(zhǔn)的基準(zhǔn)測試被廣泛地引用 如TPC C(參考// tpc ) 而且很多數(shù)據(jù)庫廠商都努力爭取在這些測試中取得好成績 這類基準(zhǔn)測試主要針對在線事務(wù)處理(OLTP)的吞吐量 非常適用于多用戶的交互式應(yīng)用 常用的測試單位是每秒事務(wù)數(shù)(TPS) 有些也采用每分鐘事務(wù)數(shù)(TPM)
響應(yīng)時間或者延遲
這個指標(biāo)用于測試任務(wù)所需的整體時間 根據(jù)具體的應(yīng)用 測試的時間單位可能是微秒 毫秒 秒或者分鐘 根據(jù)不同的時間單位可以計算出平均響應(yīng)時間 最小響應(yīng)時間 最大響應(yīng)時間和所占百分比 最大響應(yīng)時間通常意義不大 因?yàn)闇y試時間越長 最大響應(yīng)時間也可能越大 而且其結(jié)果通常不可重復(fù) 每次測試都可能得到不同的最大響應(yīng)時間 因此 通??梢允褂冒俜直软憫?yīng)時間(percentile responsetime)來替代最大響應(yīng)時間 例如 如果 % 的響應(yīng)時間都是 毫秒 則表示任務(wù)在 % 的時間段內(nèi)都可以在 毫秒之內(nèi)完成
使用圖表有助于理解測試結(jié)果 可以將測試結(jié)果繪制成折線圖(比如平均值折線或者 % 百分比折線)或者散點(diǎn)圖 直觀地表現(xiàn)數(shù)據(jù)結(jié)果集的分布情況 通過這些圖可以發(fā)現(xiàn)長時間測試的趨勢 本章后面將更詳細(xì)地討論這一點(diǎn)
并發(fā)性
并發(fā)性是一個非常重要又經(jīng)常被誤解和誤用的指標(biāo) 例如 它經(jīng)常被表示成多少用戶在同一時間瀏覽一個Web 站點(diǎn) 經(jīng)常使用的指標(biāo)是有多少個會話注 然而 HTTP協(xié)議是無狀態(tài)的 大多數(shù)用戶只是簡單地讀取瀏覽器上顯示的信息 這并不等同于Web 服務(wù)器的并發(fā)性 而且 Web 服務(wù)器的并發(fā)性也不等同于數(shù)據(jù)庫的并發(fā)性 而僅僅只表示會話存儲機(jī)制可以處理多少數(shù)據(jù)的能力 Web 服務(wù)器的并發(fā)性更準(zhǔn)確的度量指標(biāo) 應(yīng)該是在任意時間有多少同時發(fā)生的并發(fā)請求
在應(yīng)用的不同環(huán)節(jié)都可以測量相應(yīng)的并發(fā)性 Web 服務(wù)器的高并發(fā) 一般也會導(dǎo)致數(shù)據(jù)庫的高并發(fā) 但服務(wù)器采用的語言和工具集對此都會有影響 注意不要將創(chuàng)建數(shù)據(jù)庫連接和并發(fā)性搞混淆 一個設(shè)計良好的應(yīng)用 同時可以打開成百上千個MySQL 數(shù)據(jù)庫服務(wù)器連接 但可能同時只有少數(shù)連接在執(zhí)行查詢 所以說 一個Web 站點(diǎn) 同時有 個用戶 訪問 卻可能只有 ~ 個并發(fā)請求到MySQL 數(shù)據(jù)庫
換句話說 并發(fā)性基準(zhǔn)測試需要關(guān)注的是正在工作中的并發(fā)操作 或者是同時工作中的線程數(shù)或者連接數(shù) 當(dāng)并發(fā)性增加時 需要測量吞吐量是否下降 響應(yīng)時間是否變長 如果是這樣 應(yīng)用可能就無法處理峰值壓力
并發(fā)性的測量完全不同于響應(yīng)時間和吞吐量 它不像是一個結(jié)果 而更像是設(shè)置基準(zhǔn)測試的一種屬性 并發(fā)性測試通常不是為了測試應(yīng)用能達(dá)到的并發(fā)度 而是為了測試應(yīng)用在不同并發(fā)下的性能 當(dāng)然 數(shù)據(jù)庫的并發(fā)性還是需要測量的 可以通過sy *** ench 指定 或者 個線程的測試 然后在測試期間記錄MySQL 數(shù)據(jù)庫的Threads_running 狀態(tài)值 在第 章將討論這個指標(biāo)對容量規(guī)劃的影響
可擴(kuò)展性
在系統(tǒng)的業(yè)務(wù)壓力可能發(fā)生變化的情況下 測試可擴(kuò)展性就非常必要了 第 章將更進(jìn)一步討論可擴(kuò)展性的話題 簡單地說 可擴(kuò)展性指的是 給系統(tǒng)增加一倍的工作 在理想情況下就能獲得兩倍的結(jié)果(即吞吐量增加一倍) 或者說 給系統(tǒng)增加一倍的資源(比如兩倍的CPU 數(shù)) 就可以獲得兩倍的吞吐量 當(dāng)然 同時性能(響應(yīng)時間)也必須在可以接受的范圍內(nèi) 大多數(shù)系統(tǒng)是無法做到如此理想的線性擴(kuò)展的 隨著壓力的變化 吞吐量和性能都可能越來越差
可擴(kuò)展性指標(biāo)對于容量規(guī)范非常有用 它可以提供其他測試無法提供的信息 來幫助發(fā)現(xiàn)應(yīng)用的瓶頸 比如 如果系統(tǒng)是基于單個用戶的響應(yīng)時間測試(這是一個很糟糕的測試策略)設(shè)計的 雖然測試的結(jié)果很好 但當(dāng)并發(fā)度增加時 系統(tǒng)的性能有可能變得非常糟糕 而一個基于不斷增加用戶連接的情況下的響應(yīng)時間測試則可以發(fā)現(xiàn)這個問題
一些任務(wù) 比如從細(xì)粒度數(shù)據(jù)創(chuàng)建匯總表的批量工作 需要的是周期性的快速響應(yīng)時間 當(dāng)然也可以測試這些任務(wù)純粹的響應(yīng)時間 但要注意考慮這些任務(wù)之間的相互影響 批量工作可能導(dǎo)致相互之間有影響的查詢性能變差 反之亦然
歸根結(jié)底 應(yīng)該測試那些對用戶來說最重要的指標(biāo) 因此應(yīng)該盡可能地去收集一些需求 比如 什么樣的響應(yīng)時間是可以接受的 期待多少的并發(fā)性 等等 然后基于這些需求來設(shè)計基準(zhǔn)測試 避免目光短淺地只關(guān)注部分指標(biāo) 而忽略其他指標(biāo)
返回目錄 高性能MySQL
編輯推薦
ASP NET開發(fā)培訓(xùn)視頻教程
數(shù)據(jù)倉庫與數(shù)據(jù)挖掘培訓(xùn)視頻教程
lishixinzhi/Article/program/MySQL/201311/29741
字符串類型( )
MySQL 支持多種字符串類型 每種類型還有很多變種 這些數(shù)據(jù)類型在 和 版本發(fā)生了很大的變化 使得情況更加復(fù)雜 從MySQL 開始 每個字符串列可以定義自己的字符集和排序規(guī)則 或者說校對規(guī)則(collation)(更多關(guān)于這個主題的信息請參考第 章) 這些東西會很大程度上影響性能
VARCHAR 和CHAR 類型
VARCHAR 和CHAR 是兩種最主要的字符串類型 不幸的是 很難精確地解釋這些值是怎么存儲在磁盤和內(nèi)存中的 因?yàn)檫@跟存儲引擎的具體實(shí)現(xiàn)有關(guān) 下面的描述假設(shè)使用的存儲引擎是InnoDB 和/ 或者M(jìn)yISAM 如果使用的不是這兩種存儲引擎 請參考所使用的存儲引擎的文檔
先看看VARCHAR 和CHAR 值通常在磁盤上怎么存儲 請注意 存儲引擎存儲CHAR 或者VARCHAR 值的方式在內(nèi)存中和在磁盤上可能不一樣 所以MySQL 服務(wù)器從存儲引擎讀出的值可能需要轉(zhuǎn)換為另一種存儲格式 下面是關(guān)于兩種類型的一些比較
VARCHAR
VARCHAR 類型用于存儲可變長字符串 是最常見的字符串?dāng)?shù)據(jù)類型 它比定長類型更節(jié)省空間 因?yàn)樗鼉H使用必要的空間(例如 越短的字符串使用越少的空間) 有一種情況例外 如果MySQL 表使用ROW_FORMAT=FIXED 創(chuàng)建的話 每一行都會使用定長存儲 這會很浪費(fèi)空間
VARCHAR 需要使用 或 個額外字節(jié)記錄字符串的長度 如果列的最大長度小于或等于 字節(jié) 則只使用 個字節(jié)表示 否則使用 個字節(jié) 假設(shè)采用latin 字符集 一個VARCHAR( ) 的列需要 個字節(jié)的存儲空間 VARCHAR( ) 的列則需要 個字節(jié) 因?yàn)樾枰?個字節(jié)存儲長度信息
VARCHAR 節(jié)省了存儲空間 所以對性能也有幫助 但是 由于行是變長的 在UPDATE 時可能使行變得比原來更長 這就導(dǎo)致需要做額外的工作 如果一個行占用的空間增長 并且在頁內(nèi)沒有更多的空間可以存儲 在這種情況下 不同的存儲引擎的處理方式是不一樣的 例如 MyISAM 會將行拆成不同的片段存儲 InnoDB則需要分裂頁來使行可以放進(jìn)頁內(nèi) 其他一些存儲引擎也許從不在原數(shù)據(jù)位置更新數(shù)據(jù)
下面這些情況下使用VARCHAR 是合適的 字符串列的最大長度比平均長度大很多 列的更新很少 所以碎片不是問題 使用了像UTF 這樣復(fù)雜的字符集 每個字符都使用不同的字節(jié)數(shù)進(jìn)行存儲
在 或者更高版本 MySQL 在存儲和檢索時會保留末尾空格 但在 或更老的版本 MySQL 會剔除末尾空格
InnoDB 則更靈活 它可以把過長的VARCHAR 存儲為BLOB 我們稍后討論這個問題
CHAR
CHAR 類型是定長的 MySQL 總是根據(jù)定義的字符串長度分配足夠的空間 當(dāng)存儲CHAR 值時 MySQL 會刪除所有的末尾空格(在MySQL 和更老版本中VARCHAR也是這樣實(shí)現(xiàn)的 也就是說這些版本中CHAR 和VARCHAR 在邏輯上是一樣的 區(qū)別只是在存儲格式上) CHAR 值會根據(jù)需要采用空格進(jìn)行填充以方便比較
CHAR 適合存儲很短的字符串 或者所有值都接近同一個長度 例如 CHAR 非常適合存儲密碼的MD 值 因?yàn)檫@是一個定長的值 對于經(jīng)常變更的數(shù)據(jù) CHAR 也比VARCHAR 更好 因?yàn)槎ㄩL的CHAR 類型不容易產(chǎn)生碎片 對于非常短的列 CHAR 比VARCHAR 在存儲空間上也更有效率 例如用CHAR( ) 來存儲只有Y 和N 的值 如果采用單字節(jié)字符集注 只需要一個字節(jié) 但是VARCHAR( ) 卻需要兩個字節(jié) 因?yàn)檫€有一個記錄長度的額外字節(jié)
CHAR 類型的這些行為可能有一點(diǎn)難以理解 下面通過一個具體的例子來說明 首先 我們創(chuàng)建一張只有一個CHAR( ) 字段的表并且往里面插入一些值
當(dāng)檢索這些值的時候 會發(fā)現(xiàn)string 末尾的空格被截斷了
如果用VARCHAR( ) 字段存儲相同的值 可以得到如下結(jié)果
數(shù)據(jù)如何存儲取決于存儲引擎 并非所有的存儲引擎都會按照相同的方式處理定長和變長的字符串 Memory 引擎只支持定長的行 即使有變長字段也會根據(jù)最大長度分配最大空間 不過 填充和截取空格的行為在不同存儲引擎都是一樣的 因?yàn)檫@是在MySQL 服務(wù)器層進(jìn)行處理的
返回目錄 高性能MySQL
編輯推薦
ASP NET MVC 框架揭秘
Oracle索引技術(shù)
ASP NET開發(fā)培訓(xùn)視頻教程
lishixinzhi/Article/program/MySQL/201311/29687