程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> SqlServer數據庫 >> 關於SqlServer >> 詳解SQL Server OS的任務調度機制

詳解SQL Server OS的任務調度機制

編輯:關於SqlServer

簡介

SQL Server OS是在Windows之上,用於服務SQL Server的一個用戶級別的操作系統層次。它將操作系統部分的功能從整個SQL Server引擎中抽象出來,單獨形成一層,以便為存儲引擎提供服務。SQL Server OS主要提供了任務調度、內存分配、死鎖檢測、資源檢測、鎖管理、Buffer Pool管理等多種功能。本篇文章主要是談一談SQL OS中所提供的任務調度機制。

搶占式(Preemptive)調度與非搶占式(non-Preemptive)調度

數據庫層面的任務調度的起源是ACM上的一篇名為“Operating System Support for Database Management”。但是對於Windows來說,在操作系統層面專門加入支持數據庫的任務調度,還不如在SQL Server中專門抽象出來一層進行調度,既然可以抽象出來一層進行數據庫層面的任務調度,那麼何不在這個抽象層進行內存和IO等的管理呢?這個想法,就是SQL Server OS的起源。

在Windows NT4之後,Windows任務調度是搶占式的,也就是說Windows任務是根據任務的優先級和時間片來決定。如果一個任務的時間片用完,或是有更高優先級的任務正在等待,那麼操作系統可以強制剝奪正在運行的線程(線程是任務調度的基本單位)所占用的CPU,將CPU資源讓給其它線程。

但是對於SQL Server來說,這種非合作式的、基於時間片的任務調度機制就不那麼合適了。如果SQL Server使用Windows內的任務調度機制來進行任務調度的話,Windows不會根據SQL Server的調度機制進行優化,只是根據時間片和優先級來中斷線程,這會導致如下兩個缺陷:

Windows不會知道SQL Server中任務(也就是SQL OS中的Task,會在文章後面講到)的最佳中斷點,這勢必會造成更多的Context Switch(Context Switch代價非常非常高昂,需要線程字用戶態和核心態之間轉換),因為Windows調度不是線程本身決定是否該出讓CPU,而是由Windows決定。Windows並不會知道當前數據庫中對應的線程是否正在做關鍵任務,只會不分青紅皂白的奪取線程的CPU。

連入SQL Server的連接不可能一直在執行,每一個Batch之間會有大量空閒時間。如果每個連接都需要單獨占用一個線程,那麼SQL Server維護這些線程就需要消耗額外的資源,這是很不明智的。

而對於SQL Server OS來說,線程調度采用的合作模式而不是搶占模式。這是因為這些數據庫內的任務都在SQL Server這個SandBox之內,SQL Server充分相信其內線程,所以除非線程主動放棄CPU,SQL Server OS不會強制剝奪線程的CPU。這樣一來,雖然Worker之間的切換依然是通過Windows的Context Switch進行,但這種合作模式會大大減少所需Context Switch的次數。

SQL Server決定哪一個時間點哪一個線程運行,是通過一個叫Scheduler的東西進行的,下面讓我們來看Scheduler。

Scheduler

SQL Server中每一個邏輯CPU都有一個與之對應的Scheduler,只有拿到Scheduler所有權的任務才允許被執行,Scheduler可以看做一個隊SQLOS來說的邏輯CPU。您可以通過sys.dm_os_schedulers這個DMV來看系統中所有的Scheduler,如圖1所示。

圖1.查看sys.dm_os_schedulers

  我的筆記本是一個i7四核8線程的CPU,對應的,可以看到除了DAC和運行系統任務的HIDDEN Scheduler,剩下的Scheduler一共8個,每個對應一個邏輯CPU,用於處理內部Task。當然,您也可以通過設置Affinity來將某些Scheduler Offline,如圖2所示。注意,這個過程是在線的,無需重啟SQL Server就能實現。

圖2.設置Affinity

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved