我們在管理繁忙的 mysql
資料庫時,可能都有碰到 sys cpu 高的經歷:系統突然 sys cpu 高起來,甚至比 user cpu 高很多,這時系統 qps、tps 急劇下降。
sys cpu高是什麼造成的呢?主要有2種可能:
1. context switch 不高,但在核心態 spin,導致 sys cpu 高
2. context switch 高,每秒超過 200k,有時超過1m,過多 context switch 導致 sys cpu 高
下面我們對這兩種情況逐一分析。
mysql 在核心態 spin,說明需要系統資源,當這個資源緊張不足時,就會在核心態 spin。
有些資源,使用者程序(或執行緒)通過執行系統調或因中斷進入核心,一般來說申請這些資源的執行時間很短,當出現資源爭用時,如果採用 sleep 再喚醒機制,代價較大,因此多採用在核心態spin的策略。
例如申請記憶體或發生缺頁中斷,沒有 free 記憶體可用時,程序或執行緒就可能在核心態先執行記憶體**再執行記憶體分配,但系統記憶體是共享資源,分配**時需要鎖保護,當多個程序(或執行緒)同時**分配記憶體時。就會在核心態 spin。
當 free 記憶體不足時,可能出現這種情況。典型症狀:
mysql running 高,但系統 qps、tps 下降
系統 free 記憶體不足;或系統 free 記憶體充足時,但啟用了 numa 記憶體分配策略,有的節點 free 記憶體很少
系統 context switch 不高
mysql innodb 的 mutex、rwlock 查不到等待資訊
sar -b 顯示有 pgscand 產生
當系統記憶體不足時,mysql 突然有大量訪問,緊急需要大量記憶體,kswapd 在短時間內**不了足夠多的 free 記憶體,或 kswapd 還沒有觸發執行,這時 mysql 使用者執行緒就會在核心態執行記憶體**操作,從而出現以上症狀。
sar -b 輸出中,pgscank 是表示核心執行緒 kswapd **記憶體,k意思是 kernel;pgscand是表示使用者程序或執行緒直接**記憶體,d意思是direct。
解決辦法:保證系統有充足 free 記憶體可用,numa 環境要求每個節點都有足夠free記憶體可用。
由於 linux 系統會盡量使用 free 記憶體,乙個執行很久的 linux 系統,free記憶體通常很少,存在大量 filecache 記憶體,但 linux 沒有直接提供控制 filecache 占用多少的引數,那怎麼能夠保留足夠可用的 free 記憶體,以應對突然記憶體需求呢?
對此,linux 2.3.32+ 核心中增加乙個新的引數vm.extra_free_kbytes
,就是控制free記憶體的。
關於系統free記憶體,有2個重要引數:vm.min_free_kbytes
和vm.extra_free_kbytes
(2.6.32+)
vm.min_free_kbytes
:系統保留給核心用的記憶體。
這個值決定/proc/zoneinfo
中 zone 的min值。當系統 free 記憶體小於這個值時,kswapd 會**記憶體,直到free記憶體達到/proc/zoneinfo
中 high 值才停止**;
當使用者程序或執行緒分配記憶體或發生缺頁中斷時,free 記憶體少於vm.min_free_kbytes
,會在使用者執行緒上下文中直接進行**記憶體(pgscand)和分配記憶體。
vm.extra_free_kbytes
:系統保留給應用的free記憶體。
這個值決定了/proc/zoneinfo
中normal zone的low值。當系統free記憶體小於vm.min_free_kbytes + vm.extra_free_kbytes
時,kswapd會開始**記憶體,直到free記憶體達到/proc/zoneinfo
中high值才停止**。
這個額外的vm.extra_free_kbytes
就是給應用突發記憶體需求時使用的,避免急需記憶體時發生pgscand或kswapd**記憶體不及時。
vm.extra_free_kbytes
分配多大合適呢?一般能應對流量高峰時1-2秒記憶體需求就可以了。free記憶體減少後,kswapd程序會在後台**記憶體的,一般512m-2g可以滿足要求。
有很多種情況都會導致 context switch。mysql 中的 mutex 和 rwlock 在獲取不成功後,短暫spin,還不成功,就會發生 context switch,sleep,等待喚醒。
在 mysql中,mutex 和 rwlock導致的 context switch,一般在show global status
,show engine innodb mutex
,show engine innodb status
,performance_schema
等中會體現出來,針對不同的mutex和rwlock等待,可以採取不同的優化措施。
除了mysql的mutex和rwlock,還發現一種情況,是mysql外的mutex競爭導致context switch高。
典型症狀:
mysql running 高,但系統 qps、tps 低
系統context switch很高,每秒超過200k
在 mysql 記憶體查不到mutex和rwlock競爭資訊
sys cpu 高,user cpu 低
併發執行的sql中出現timestamp欄位,mysql的time_zone設定為system
對於使用 timestamp 的場景,mysql 在訪問 timestamp 字段時會做時區轉換,當 time_zone 設定為 system 時,mysql 訪問每一行的 timestamp 欄位時,都會通過 libc 的時區函式,獲取 linux 設定的時區,在這個函式中會持有mutex,當大量併發sql需要訪問 timestamp 欄位時,會出現 mutex 競爭。
mysql 訪問每一行都會做這個時區轉換,轉換完後釋放mutex,所有等待這個 mutex 的執行緒全部喚醒,結果又會只有乙個執行緒會成功持有 mutex,其餘又會再次sleep,這樣就會導致 context switch 非常高但 qps 很低,系統吞吐量急劇下降。
解決辦法:設定time_zone=』+8:00』,這樣就不會訪問 linux 系統時區,直接轉換,避免了mutex問題。
另外,對於spin消耗,mysql配置變數中的innodb_spin_wait_delay
和innodb_sync_spin_loops
可以用於微調。
mysql資料庫高併發處理
總體思想 短,少,分流 短 1.頁面靜態化,2.使用快取 3.使用儲存過程,對於處理一次請求需要多次訪問資料庫的操作,將操作整合到儲存過程,這樣只需要一次資料庫訪問 4.延遲修改,將修改請求儲存到記憶體中,但可能會斷電丟失資料 5.使用索引 少 1.分表,但應盡量避免多表關聯查詢 2.分離活躍資料,...
MySQL資料庫高併發優化配置
在apache,php,mysql的體系架構中,mysql對於效能的影響最大,也是關鍵的核心部分。對於discuz 論壇程式也是如此,mysql的設定是否合理優化,直接 影響到論壇的速度和承載量!同時,mysql也是優化難度最大的乙個部分,不但需要理解一些mysql專業知識,同時還需要長時間的觀察統...
MySQL資料庫高併發優化配置
在apache,php,mysql的體系架構中,mysql對於效能的影響最大,也是關鍵的核心部分。對於discuz 論壇程式也是如此,mysql的設定是否合理優化,直接 影響到論壇的速度和承載量!同時,mysql也是優化難度最大的乙個部分,不但需要理解一些mysql專業知識,同時還需要長時間的觀察統...