人人都是 DBA(III)SQL Server 调度器
在 SQL Server 中,當數(shù)據(jù)庫啟動后,SQL Server 會為每個物理 CPU(包括 Physical CPU 和 Hyperthreaded)創(chuàng)建一個對應的任務調(diào)度器(Scheduler),Scheduler 可以看作為邏輯 CPU(Logical CPU)。
根據(jù) Affinity Mask 選項的配置,Scheduler 的狀態(tài)被設(shè)置為 ONLINE 或 OFFLINE。使用下面的 SQL 來查詢當前環(huán)境中 Scheduler 的狀態(tài)。
SELECT is_online,[status],COUNT(*) AS [count] FROM sys.dm_os_schedulers WHERE scheduler_id < 255 GROUP BY is_online,[status];默認的 Affinity Mask 是 0,也就是所有 Scheduler 均為 ONLINE。
SELECT * FROM sys.configurations WHERE [name] LIKE '%affinity%';例如,如果把 Affinity Mask 設(shè)置為 3,即 00000011,則意味著只有 0 和 1 號 CPU 可以使用。
假設(shè)有 64 個 CPU,則常用的 Affinity Mask 值有:
- 255 -> 0xFF
- 65280 ->?0xFF00
- 16711680 ->?0xFF0000
- 4278190080 ->?0xFF000000
- 4294967040?->?0xFFFFFF00
- -256 -> 0xFFFFFF00
下面的 VM 的配置為 4 * 8 = 32 Logical CPUs 情況。
設(shè)置 NumaNode0 上的 8 個 CPU 用于 I/O,其他 3 個節(jié)點用于 Processor。
Scheduler 負責根據(jù)需求創(chuàng)建和銷毀 Worker,一個 Worker 即可是一個 Thread 也可以是一個 Fiber,可以通過 Max Worker Threads 和 Use Windows Fibers 配置項來進行設(shè)置。
Max Worker Threads 選項負責限制線程池(Threading Pool)中線程的最大數(shù)量。
SELECT * FROM sys.configurations WHERE [name] LIKE '%worker%';默認值為 0,即允許 SQL Server 根據(jù) CPU 和版本情況進行自動配置最大線程數(shù)量。
| ?Number of CPUs | ?32-bit Computor? | ?64-bit Computor? |
| ?<= 4 processors? | ?256 | ?512 |
| 8 processors | ?288 | ?576 |
| ?16 processors | ?352 | ?704 |
| ?32 processors | ?480 | ?960 |
| ?64 processors | ?736 | ?1472 |
可以使用 sp_configure 來配置該選項。
EXEC sp_configure 'show advanced options', 1; GO RECONFIGURE; GOEXEC sp_configure 'max worker threads', 900; GO RECONFIGURE; GO使用如下 SQL 查詢來查看當前數(shù)據(jù)庫環(huán)境中的 Max Workers Count 和 Current Workers Count。
SELECT max_workers_count FROM sys.dm_os_sys_info; SELECT SUM(current_workers_count) AS current_workers_count FROM sys.dm_os_schedulers;
Worker 直接使用 Scheduler,每個 Worker 只會關(guān)聯(lián)到 1 個 Scheduler,Worker 不能從一個 Scheduler 轉(zhuǎn)移到另一個 Scheduler 上。
Worker 處理的工作單元可以是一個 Request,也可以是一個 Task。比如批處理 Request 可能被分解成多個 Task。當 Scheduler 接收到新的 Request 或 Task 請求時,如果當前沒有空閑 Worker(Idle Worker),則根據(jù)配置開始創(chuàng)建新的 Worker,而 Request 或 Task 將被綁定到該 Worker 上。
SELECT is_idle,COUNT(*) AS [count] FROM sys.dm_os_schedulers WHERE scheduler_id < 255AND is_online = 1 GROUP BY is_idle;sys.dm_os_schedulers 中的 scheduler_id < 255 則為常規(guī)查詢,如果 scheduler_id >= 255 則為系統(tǒng)內(nèi)調(diào)度。
如果 Worker 已經(jīng)空閑了至少 15 分鐘以上,或者 SQL Server 檢測到有內(nèi)存壓力時,空閑的 Worker 可能被銷毀。
- 在 32 位機上,1 個 Worker 至少占用 0.5M 的內(nèi)存。
- 在 64 位機上,1 個 Worker 至少占用 2M 的內(nèi)存。
所以,銷毀空閑的 Worker 以釋放內(nèi)存可以立即改善系統(tǒng)對內(nèi)存的迫切需求。
SQL Server 設(shè)計了非常高效的 Worker Pool,所以即使有大量的并發(fā)在訪問數(shù)據(jù)庫,可能 Worker Pool 的大小仍遠小于配置的 Max Worker Threads 的值。但盡管如此,如果 Worker 中處理的 Task 發(fā)生了鎖定或者等待 IO 完成等阻塞操作,Worker 即會被阻塞,Worker 不會其他任何請求直到阻塞條件解除。
SELECT AVG(current_workers_count) AS [avg_current_workers_count],AVG(active_workers_count) AS [avg_active_workers_count],MAX(current_workers_count) AS [max_current_workers_count],MAX(active_workers_count) AS [max_active_workers_count],SUM(current_workers_count) AS [total_current_workers_count],SUM(active_workers_count) AS [total_active_workers_count],SUM(pending_disk_io_count) AS [total_pending_disk_io_count] FROM sys.dm_os_schedulers WHERE scheduler_id < 255AND is_online = 1;SQL Server 中的 Session 實際上只描述了建立連接后的通道,通過該通道可以發(fā)送 Request,通道也可以保持空閑。所以 Session 不會與特定的 Scheduler 進行綁定。
SELECT s.session_id,r.command,r.[status],r.wait_type,r.scheduler_id,w.is_preemptive,t.task_state,u.cpu_id FROM sys.dm_exec_sessions AS s INNER JOIN sys.dm_exec_requests AS r ON s.session_id = r.session_id INNER JOIN sys.dm_os_tasks AS t ON r.task_address = t.task_address INNER JOIN sys.dm_os_workers AS w ON t.worker_address = w.worker_address INNER JOIN sys.dm_os_schedulers AS u ON t.scheduler_id = u.scheduler_id WHERE s.is_user_process = 0 ORDER BY r.scheduler_id;當 Session 建立后,會將當前負載最低的 Scheduler 分配給該 Session。然后,當 Session 中有新的 Request 抵達時,SQL Server 會將最近處理過該 SPID 中 Request 的 Scheduler 作為推薦的調(diào)度器(Preferred Scheduler)優(yōu)先調(diào)度。盡管如此,當 Session 中抵達的 Request 開始排隊時,SQL Server 會計算每個 Scheduler 的 Load Factor,尋找負載最低的 Scheduler 來處理任務。
?
《人人都是 DBA》系列文章索引:
| ?序號? | ?名稱? |
| 1 | ?人人都是 DBA(I)SQL Server 體系結(jié)構(gòu) |
| 2 | ?人人都是 DBA(II)SQL Server 元數(shù)據(jù) |
| 3 | ?人人都是 DBA(III)SQL Server 調(diào)度器 |
| 4 | ?人人都是 DBA(IV)SQL Server 內(nèi)存管理 |
| 5 | ?人人都是 DBA(V)SQL Server 數(shù)據(jù)庫文件 |
| 6 | ?人人都是 DBA(VI)SQL Server 事務日志 |
| 7 | ?人人都是 DBA(VII)B 樹和 B+ 樹 |
| 8 | ?人人都是 DBA(VIII)SQL Server 頁存儲結(jié)構(gòu) |
| 9 | ?人人都是 DBA(IX)服務器信息收集腳本匯編 |
| 10 | ?人人都是 DBA(X)資源信息收集腳本匯編 |
| 11 | ?人人都是 DBA(XI)I/O 信息收集腳本匯編 |
| 12 | ?人人都是 DBA(XII)查詢信息收集腳本匯編 |
| 13 | ?人人都是 DBA(XIII)索引信息收集腳本匯編 |
| 14 | ?人人都是 DBA(XIV)存儲過程信息收集腳本匯編? |
| 15 | ?人人都是 DBA(XV)鎖信息收集腳本匯編 |
本文轉(zhuǎn)自匠心十年博客園博客,原文鏈接:http://www.cnblogs.com/gaochundong/p/everyone_is_a_dba_sqlserver_scheduler.html,如需轉(zhuǎn)載請自行聯(lián)系原作者
總結(jié)
以上是生活随笔為你收集整理的人人都是 DBA(III)SQL Server 调度器的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: RxJava+Retrofit+MVP+
- 下一篇: grenndao 插入表数据报错