主頁 > 知識庫 > SqlServer應(yīng)用之sys.dm_os_waiting_tasks 引發(fā)的疑問(中)

SqlServer應(yīng)用之sys.dm_os_waiting_tasks 引發(fā)的疑問(中)

熱門標(biāo)簽:臺灣外呼系統(tǒng)軟件 樂昌電話機器人 南通智能外呼系統(tǒng)怎么樣 真3地圖標(biāo)注 南京怎么申請400這種電話 地圖標(biāo)注可以編輯地名嗎 濮陽清豐400開頭的電話申請 地圖標(biāo)注跑線下市場 疫情時期電話機器人

 通過上篇文章給大家介紹了SqlServer應(yīng)用之sys.dm_os_waiting_tasks 引發(fā)的疑問(上) ,說了一下sys.dm_exec_requests 和 sys.dm_os_waiting_tasks 在獲取并行等待的時候得不同結(jié)果,這一篇我們談?wù)撓挛业牡诙€疑問:為什么一個并行計劃(4線程)卻一下出現(xiàn)了那么多等待,SQL的并行到底是怎么執(zhí)行的?。。?!

    先貼以下上篇sys.dm_os_waiting_tasks 的結(jié)果圖:

     我們分析一下這個結(jié)果的task_address 可以看出去掉重復(fù)其實只有9個,也就是說一個并行(4線程,配置不同,情況也不同)會有9個task。 又是線程,又是task ,還有worker,schedulers 這些都是什么? 這個有必要先說一下,因為這篇博客前我也是亂亂的。

 scheduler

對于每個邏輯CPU,SQLSERVER會有一個scheduler與之對應(yīng),在SQL層面上代表CPU對象,只有拿到scheduler所有權(quán)的任務(wù)worker才能在這個邏輯CPU上運行

所謂邏輯CPU,就是SQLSERVER從Windows層面上看到的CPU數(shù)目,如果是一個雙核的CPU,那么一個物理CPU在SQL看來就是兩個邏輯CPU。如果系統(tǒng)還使用了

超線程hyper-threaded ,那對SQLSERVER來講就是4個邏輯CPU

規(guī)則: 每個scheduler上的最大worker數(shù)目等于SQLSERVER的最大線程數(shù)除以scheduler的數(shù)目 ,在同一個時間點,只能有一個擁有scheduler的worker處于運行狀態(tài),其他worker都必須處于等待狀態(tài)。這樣能降低每個邏輯CPU上的處于正在運行狀態(tài)的線程數(shù)目,降低context switch,提供可擴展性scheduler是SQLSERVER的一個邏輯概念,他不與物理CPU相綁定。也就是說,一個scheduler可以被Windows安排一會兒在這個CPU上,一會兒在那個CPU上。

 但是,如果在sp_configure里設(shè)置了CPU affinity mask,那么scheduler就會固定在某個特定的CPU上

worker

每個worker跟一個線程(或纖程fiber)相對應(yīng),是SQLSERVER任務(wù)的執(zhí)行單位。SQLSERVER不直接調(diào)度線程/纖程,而是調(diào)度worker,使得SQLSERVER能夠控制

任務(wù)調(diào)度

規(guī)則: 每個worker會固定代表一個線程(或纖程),并且和一個scheduler相綁定。如果scheduler是固定在某個CPU上的(通過設(shè)置CPU affinity mask),那么worker也會固定在某個CPU上每個scheduler有worker的上限值,并且可以根據(jù)SQLSERVER工作負(fù)荷創(chuàng)建或釋放worker,每次worker都會去運行一個完整的任務(wù)(task)。在任務(wù)做完之前不會退出,除非這個任務(wù)主動進(jìn)入等待狀態(tài)。

scheduler只在有新任務(wù)要運行,而當(dāng)前沒有空閑的worker的情況下,才會創(chuàng)建新的worker。

某個worker空閑超過15分鐘,scheduler可能會刪除這個worker,以及其對應(yīng)的線程。當(dāng)SQLSERVER遇到內(nèi)存壓力的時,也會大量刪除處于空閑狀態(tài)的worker,以節(jié)省multi-page的內(nèi)存開銷各種CPU和SQLSERVER版本組合自動配置的最大工作線程數(shù)CPU數(shù)                 32位計算機                        64位計算機
=4                     256                                  512
8                          288                                  576
16                        352                                  704
32                        480                                  960

task

在worker上運行的最小任務(wù)單元。最簡單的task就是一個簡單batch。例如,客戶發(fā)過來下面的請求:

 SELECT @@SERVERNAME
 GO
 SELECT GETDATE()
 GO 

那么這兩個batch就分別是兩個task。SQLSERVER會先分配給第一個batch(select @@servername)一個worker,將結(jié)果返回給客戶端,再分配第二個batch

(select getdate())一個worker。這兩個worker可能是不同的worker,甚至在不同的scheduler上只要一個task開始運行,他就不會從這個worker上被移出。例如,如果一個select語句被其他連接阻塞住,worker就不能繼續(xù)運行,只能進(jìn)入等待狀態(tài)。但是這個select task 不會將這個worker釋放,讓他做其他任務(wù)。所以結(jié)果是這個worker所對應(yīng)的線程會進(jìn)入等待狀態(tài)

yielding

 SQLOS的任務(wù)調(diào)度算法的核心,就是所有在邏輯scheduler上運行的worker都是非搶占式的 (non-preemptive)。worker始終在scheduler上運行,直到他運行結(jié)束,或者主動將scheduler讓出給其他worker為止。這個“讓出”scheduler的動作,我們叫yieding每個scheduler都會有一個runnable列表,所有等待CPU運行的worker都會在這個列表里排隊,以先進(jìn)先出的算法,等待SQL分配給他scheduler運行SQLSERVER定義了很多yieding的規(guī)則,約束一個task在scheduler運行的時間。如果task比較復(fù)雜,不能很快完成,會保證task在合適的時間點做yieding,不至于占用scheduler太多時間。

常見時間點:

1、當(dāng)worker每次要去讀數(shù)據(jù)頁的時候,SQLSERVER會檢查這個worker已經(jīng)在scheduler上運行了多久,如果已經(jīng)超過4ms,就做yielding

2、每做64KB的結(jié)果集排序,就會做一次yielding

3、在做語句編譯compile的過程中(這個過程比較占CPU資源),經(jīng)常會有yieding

4、如果客戶端不能及時把結(jié)果集取走,worker就會做yieding

5、一個batch里的每一句話做完,都會做一次yieding

正常來講,哪怕一個task要做很久,他使用的worker是會經(jīng)常做yieding的,不會長時間占用CPU不放。如果在一個scheduler上同時有很多worker要運行,SQLSERVER通過worker自動yielding的方式調(diào)度并發(fā)運行。這個比Windows用上下文切換context switch更有效

    另附一張手繪圖

    另外推薦一篇 SQL SERVER SQLOS的任務(wù)調(diào)度 微軟亞太的官方博客

    我們大概了解了一下SQL SERVER SQLOS的任務(wù)調(diào)度 我們回到我們的并行話題看一下這個并行執(zhí)行的調(diào)度情況: 


    一個并行處理分配給了9個task,同時也啟用了9個worker,由4個scheduler調(diào)度,每個scheduler分別由一個申請數(shù)據(jù),另一個等待。那么申請數(shù)據(jù)的是可以理解的,等待的是干什么的呢?個人理解和當(dāng)前的執(zhí)行計劃有關(guān),4個線程取得數(shù)據(jù)后要做匯總的操作SQL不會等待數(shù)據(jù)獲取以后再開啟線程接收,而是接收線程在獲取數(shù)據(jù)的時候等待。

     

 疑問得到解決了么?因為已經(jīng)標(biāo)記為中篇,可見還是有疑問呀!?。。∥覀兝^續(xù)下一篇吧....

您可能感興趣的文章:
  • SqlServer應(yīng)用之sys.dm_os_waiting_tasks 引發(fā)的疑問(上)
  • SQL Server 2016里的sys.dm_exec_input_buffer的問題

標(biāo)簽:福建 通遼 廣安 馬鞍山 南京 阿里 河北 陜西

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《SqlServer應(yīng)用之sys.dm_os_waiting_tasks 引發(fā)的疑問(中)》,本文關(guān)鍵詞  SqlServer,應(yīng),用之,sys.dm,waiting,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請?zhí)峁┫嚓P(guān)信息告之我們,我們將及時溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。
  • 相關(guān)文章
  • 下面列出與本文章《SqlServer應(yīng)用之sys.dm_os_waiting_tasks 引發(fā)的疑問(中)》相關(guān)的同類信息!
  • 本頁收集關(guān)于SqlServer應(yīng)用之sys.dm_os_waiting_tasks 引發(fā)的疑問(中)的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章