Rico Chen https://medium.com/ricos-note 版權所有,請勿非法複製、散佈
第二章 高 CPU 使用率
一般來說高 CPU 使用率很容易觀察,如果伺服器(Server) CPU 持續 10~15 分鐘
維持 75~80%使用率以上(並非突發性),然後系統效能逐漸降低,那麼 SQL
Server 可能存在 CPU 瓶頸(Bottleneck),也意味過度使用 CPU 將有嚴重後
果,但要診斷出造成高 CPU 真正兇手並不容易(排除明顯錯誤),因有可能是
Memory 不足,導致 SQL Server 需搬移記憶體資料到硬碟、硬碟頻頸(過度
Switch)造成 CPU 負擔過大…等導致高 CPU 現象,簡單說系統是整體來看的,
SQL Server 所有動作幾乎都會使用到 CPU 資源,如執行查詢、編譯和重新編
譯…等,如 Server 又存在多種服務(非服務單一 SQL Server ),高 CPU 壓力來
源可能來自 AP 或其他應用服務,又或是身處虛擬環境的話,那麼複雜度將提
高不少,當然,如果你已經證實某句查詢所引起 CPU 壓力,我們即可直接嘗試
看看有無改寫 SQL Code 或優化機會,而這也是我個人最常見兇手之一,其次
就是 OLTP 系統存在大量 Blocking 導致 Worker 不足(Worker queue 會越來越
大)、不正確的平行化查詢陳述式(不良查詢或不正確索引)和記憶體不足(過度
Switch),造成 CPU 持續維持 90%以上,不幸的是,我沒有很快的方法找出形
成 CPU 壓力主因,我只能縮小可能發生的原因範圍,並透過工具所收集的資訊
逐一交叉驗證比對,抽絲剝繭找出兇手,這章我會介紹 CPU 組態選項和常見原
因,也會透過 DMV 查看相關等待類型來確認 CPU 是否存在壓力,也會提供相
Rico Chen https://medium.com/ricos-note 版權所有,請勿非法複製、散佈
關常見原因個人思路和解決方法。
2.1 17883 錯誤
身為一個商用資料庫,基本就是要有能力同時處理成千上萬的使用者並發請
求,SQLOS 核心之一的非搶占式(Non-preemptive)任務排程(Task Scheduler)
機制更優於 Windows,Task 會被分配到某 Scheduler 上,Scheduler 中有多個
Worker 供 Task 使用(圖三),如發生 Worker 數量不足,那麼新的 Task 將進入
等待 Worker 狀態。另外也較 Windows 少發生執行緒工作內容切換(Context
switch)操作,SQLOS 自行控制也可避免被 Windows 強制中斷(Interrupted)意
外,因每條使用者 Session 對 SQL Server 來說一樣重要,每條執行緒(Thread)
優先權(除 DAC-Dedicated Administrator Connection 和一些內部定期 Task 有
較高優先權)也都相同,所以我們不會看到 2000 個使用者發出請求,SQL
Server 也分配 2000 條執行緒這樣較無效率的機制(大概分配 400 條執行緒甚至
更少),透過 11GetSchedulerStatus.sql 可查看目前 Scheduler 狀態,快速了解
Scheduler 所對應的 CPU 是否忙碌。
 max worker threads 選項可讓 SQL Server 服務更多請求數量,如需調整,
請依據 SQL Server 版本、CPU 架構和數量進行修改(圖二),可參考
Configure the max worker threads Server Configuration Option
Rico Chen https://medium.com/ricos-note 版權所有,請勿非法複製、散佈
圖 2 擷取微軟 BOL 部分內容
圖三 Scheduler、Worker 和 Task 示意圖
Rico Chen https://medium.com/ricos-note 版權所有,請勿非法複製、散佈
SQL Server 內部每 5 秒監控 Scheduler 執行狀態,如果發現某個工作(Task)在
Scheduler 上占用 CPU 超過 60 秒沒進行 Yeilding(Yeilding 是一種主動讓出
Scheduler 給其他 Worker 行為,Worker 屬於 non-Preemptive),監控機制就
會在 ErrorLog 檔案中寫下 17883 錯誤內容(圖四),這時如果 Worker queue 大
於 0(表示 Worker 不足),SQL Server 回應會緩慢甚至無回應,而我們就必須介
入並分析為何發生該問題。
圖四 17883 錯誤內容
 參考 How To Diagnose and Correct Errors 17883, 17884, 17887, and 17888
Rico Chen https://medium.com/ricos-note 版權所有,請勿非法複製、散佈
2.2 CPU 伺服器組態選項
SQL Server CPU 使用率和使用者所送出情求的工作負載最有關係,但微軟提供
CPU 讓我們自行設定的選項很有限,下面列出我個人認為需了解的相關選項,
下面選項異動請務必依照所屬環境,進行效能測試和驗證,避免發生效能越搞
越糟。
 cost threshold for parallelism : 觸發啟用平行處理門檻,預設值為 5。SQL
Server 預設優先使用非平行處理,但 SQL Server 編譯階段同時會預估候選計
畫成本(Cost),如果 Cost 大於該值設定(這裡的 Cost 估計是指,一秒執行一個
 17883 常見發生主因是 I/O 發生問題(如防毒軟體造成),SQL Server 呼叫讀
或寫檔案函式,長時間卻沒有接收到函式所返回的結果,這時我們須檢查每
個 Disk 吞吐量是否正常,下面我補充 17883 一些重要資訊,可幫助我們更了
解問題本質
1 Kernel mode 時間很長,表示當前 Thread 執行某核心功能,如要找到根本
問題,需進行 Kernel mode 的 Debug,但大部分我們只能透過 OS Hotfix 修
補,這可能是 OS 本身或某驅動程式所導致。
2 User mode 時間很長,表示當前 Thread 執行某部分程式碼但長時間沒返
回結果,但大部分我們只能夠過 SQL Server Hotfix 修補,這可能是 SQL Server
程式碼的缺陷。
3 系統閒置率(System Idle)和處理程序使用率(Process Utilization)都很低,表
示是其他應用程式或 OS 本身發生高 CPU 現象,造成 SQL Server 無法取得
CPU 資源執行 Thread,可透過 sys.dm_os_performance_counters 查詢 CPU 相
關效能計數器(參考找出硬體 Bottleneck 我部落格內容)即可確認。

SQL Server全集中實戰效能調校指引-第二章部分試讀

  • 1.
    Rico Chen https://medium.com/ricos-note版權所有,請勿非法複製、散佈 第二章 高 CPU 使用率 一般來說高 CPU 使用率很容易觀察,如果伺服器(Server) CPU 持續 10~15 分鐘 維持 75~80%使用率以上(並非突發性),然後系統效能逐漸降低,那麼 SQL Server 可能存在 CPU 瓶頸(Bottleneck),也意味過度使用 CPU 將有嚴重後 果,但要診斷出造成高 CPU 真正兇手並不容易(排除明顯錯誤),因有可能是 Memory 不足,導致 SQL Server 需搬移記憶體資料到硬碟、硬碟頻頸(過度 Switch)造成 CPU 負擔過大…等導致高 CPU 現象,簡單說系統是整體來看的, SQL Server 所有動作幾乎都會使用到 CPU 資源,如執行查詢、編譯和重新編 譯…等,如 Server 又存在多種服務(非服務單一 SQL Server ),高 CPU 壓力來 源可能來自 AP 或其他應用服務,又或是身處虛擬環境的話,那麼複雜度將提 高不少,當然,如果你已經證實某句查詢所引起 CPU 壓力,我們即可直接嘗試 看看有無改寫 SQL Code 或優化機會,而這也是我個人最常見兇手之一,其次 就是 OLTP 系統存在大量 Blocking 導致 Worker 不足(Worker queue 會越來越 大)、不正確的平行化查詢陳述式(不良查詢或不正確索引)和記憶體不足(過度 Switch),造成 CPU 持續維持 90%以上,不幸的是,我沒有很快的方法找出形 成 CPU 壓力主因,我只能縮小可能發生的原因範圍,並透過工具所收集的資訊 逐一交叉驗證比對,抽絲剝繭找出兇手,這章我會介紹 CPU 組態選項和常見原 因,也會透過 DMV 查看相關等待類型來確認 CPU 是否存在壓力,也會提供相
  • 2.
    Rico Chen https://medium.com/ricos-note版權所有,請勿非法複製、散佈 關常見原因個人思路和解決方法。 2.1 17883 錯誤 身為一個商用資料庫,基本就是要有能力同時處理成千上萬的使用者並發請 求,SQLOS 核心之一的非搶占式(Non-preemptive)任務排程(Task Scheduler) 機制更優於 Windows,Task 會被分配到某 Scheduler 上,Scheduler 中有多個 Worker 供 Task 使用(圖三),如發生 Worker 數量不足,那麼新的 Task 將進入 等待 Worker 狀態。另外也較 Windows 少發生執行緒工作內容切換(Context switch)操作,SQLOS 自行控制也可避免被 Windows 強制中斷(Interrupted)意 外,因每條使用者 Session 對 SQL Server 來說一樣重要,每條執行緒(Thread) 優先權(除 DAC-Dedicated Administrator Connection 和一些內部定期 Task 有 較高優先權)也都相同,所以我們不會看到 2000 個使用者發出請求,SQL Server 也分配 2000 條執行緒這樣較無效率的機制(大概分配 400 條執行緒甚至 更少),透過 11GetSchedulerStatus.sql 可查看目前 Scheduler 狀態,快速了解 Scheduler 所對應的 CPU 是否忙碌。  max worker threads 選項可讓 SQL Server 服務更多請求數量,如需調整, 請依據 SQL Server 版本、CPU 架構和數量進行修改(圖二),可參考 Configure the max worker threads Server Configuration Option
  • 3.
    Rico Chen https://medium.com/ricos-note版權所有,請勿非法複製、散佈 圖 2 擷取微軟 BOL 部分內容 圖三 Scheduler、Worker 和 Task 示意圖
  • 4.
    Rico Chen https://medium.com/ricos-note版權所有,請勿非法複製、散佈 SQL Server 內部每 5 秒監控 Scheduler 執行狀態,如果發現某個工作(Task)在 Scheduler 上占用 CPU 超過 60 秒沒進行 Yeilding(Yeilding 是一種主動讓出 Scheduler 給其他 Worker 行為,Worker 屬於 non-Preemptive),監控機制就 會在 ErrorLog 檔案中寫下 17883 錯誤內容(圖四),這時如果 Worker queue 大 於 0(表示 Worker 不足),SQL Server 回應會緩慢甚至無回應,而我們就必須介 入並分析為何發生該問題。 圖四 17883 錯誤內容  參考 How To Diagnose and Correct Errors 17883, 17884, 17887, and 17888
  • 5.
    Rico Chen https://medium.com/ricos-note版權所有,請勿非法複製、散佈 2.2 CPU 伺服器組態選項 SQL Server CPU 使用率和使用者所送出情求的工作負載最有關係,但微軟提供 CPU 讓我們自行設定的選項很有限,下面列出我個人認為需了解的相關選項, 下面選項異動請務必依照所屬環境,進行效能測試和驗證,避免發生效能越搞 越糟。  cost threshold for parallelism : 觸發啟用平行處理門檻,預設值為 5。SQL Server 預設優先使用非平行處理,但 SQL Server 編譯階段同時會預估候選計 畫成本(Cost),如果 Cost 大於該值設定(這裡的 Cost 估計是指,一秒執行一個  17883 常見發生主因是 I/O 發生問題(如防毒軟體造成),SQL Server 呼叫讀 或寫檔案函式,長時間卻沒有接收到函式所返回的結果,這時我們須檢查每 個 Disk 吞吐量是否正常,下面我補充 17883 一些重要資訊,可幫助我們更了 解問題本質 1 Kernel mode 時間很長,表示當前 Thread 執行某核心功能,如要找到根本 問題,需進行 Kernel mode 的 Debug,但大部分我們只能透過 OS Hotfix 修 補,這可能是 OS 本身或某驅動程式所導致。 2 User mode 時間很長,表示當前 Thread 執行某部分程式碼但長時間沒返 回結果,但大部分我們只能夠過 SQL Server Hotfix 修補,這可能是 SQL Server 程式碼的缺陷。 3 系統閒置率(System Idle)和處理程序使用率(Process Utilization)都很低,表 示是其他應用程式或 OS 本身發生高 CPU 現象,造成 SQL Server 無法取得 CPU 資源執行 Thread,可透過 sys.dm_os_performance_counters 查詢 CPU 相 關效能計數器(參考找出硬體 Bottleneck 我部落格內容)即可確認。