人人都是 DBA(III)SQL Server 调度器

news/2024/7/19 9:28:32 标签: 数据库, 爬虫, 操作系统

在 SQL Server 中,当数据库启动后,SQL Server 会为每个物理 CPU(包括 Physical CPU 和 Hyperthreaded)创建一个对应的任务调度器(Scheduler),Scheduler 可以看作为逻辑 CPU(Logical CPU)。

根据 Affinity Mask 选项的配置,Scheduler 的状态被设置为 ONLINE 或 OFFLINE。使用下面的 SQL 来查询当前环境中 Scheduler 的状态。

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 设置为 3,即 00000011,则意味着只有 0 和 1 号 CPU 可以使用。

假设有 64 个 CPU,则常用的 Affinity Mask 值有:

  • 255 -> 0xFF
  • 65280 -> 0xFF00
  • 16711680 -> 0xFF0000
  • 4278190080 -> 0xFF000000
  • 4294967040 -> 0xFFFFFF00
  • -256 -> 0xFFFFFF00

下面的 VM 的配置为 4 * 8 = 32 Logical CPUs 情况。

设置 NumaNode0 上的 8 个 CPU 用于 I/O,其他 3 个节点用于 Processor。

Scheduler 负责根据需求创建和销毁 Worker,一个 Worker 即可是一个 Thread 也可以是一个 Fiber,可以通过 Max Worker Threads 和 Use Windows Fibers 配置项来进行设置。

Max Worker Threads 选项负责限制线程池(Threading Pool)中线程的最大数量。

SELECT *
FROM sys.configurations
WHERE [name] LIKE '%worker%';

默认值为 0,即允许 SQL Server 根据 CPU 和版本情况进行自动配置最大线程数量。

 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;
GO

EXEC sp_configure 'max worker threads', 900;
GO
RECONFIGURE;
GO

使用如下 SQL 查询来查看当前数据库环境中的 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 只会关联到 1 个 Scheduler,Worker 不能从一个 Scheduler 转移到另一个 Scheduler 上。

Worker 处理的工作单元可以是一个 Request,也可以是一个 Task。比如批处理 Request 可能被分解成多个 Task。当 Scheduler 接收到新的 Request 或 Task 请求时,如果当前没有空闲 Worker(Idle Worker),则根据配置开始创建新的 Worker,而 Request 或 Task 将被绑定到该 Worker 上。

SELECT is_idle
    ,COUNT(*) AS [count]
FROM sys.dm_os_schedulers
WHERE scheduler_id < 255
    AND is_online = 1
GROUP BY is_idle;

sys.dm_os_schedulers 中的 scheduler_id < 255 则为常规查询,如果 scheduler_id >= 255 则为系统内调度。

如果 Worker 已经空闲了至少 15 分钟以上,或者 SQL Server 检测到有内存压力时,空闲的 Worker 可能被销毁。

  • 在 32 位机上,1 个 Worker 至少占用 0.5M 的内存。
  • 在 64 位机上,1 个 Worker 至少占用 2M 的内存。

所以,销毁空闲的 Worker 以释放内存可以立即改善系统对内存的迫切需求。

SQL Server 设计了非常高效的 Worker Pool,所以即使有大量的并发在访问数据库,可能 Worker Pool 的大小仍远小于配置的 Max Worker Threads 的值。但尽管如此,如果 Worker 中处理的 Task 发生了锁定或者等待 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 < 255
    AND is_online = 1;

SQL Server 中的 Session 实际上只描述了建立连接后的通道,通过该通道可以发送 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 作为推荐的调度器(Preferred Scheduler)优先调度。尽管如此,当 Session 中抵达的 Request 开始排队时,SQL Server 会计算每个 Scheduler 的 Load Factor,寻找负载最低的 Scheduler 来处理任务。

 

《人人都是 DBA》系列文章索引:

 序号 

 名称 

1

 人人都是 DBA(I)SQL Server 体系结构

2

 人人都是 DBA(II)SQL Server 元数据

3

 人人都是 DBA(III)SQL Server 调度器

4

 人人都是 DBA(IV)SQL Server 内存管理

5

 人人都是 DBA(V)SQL Server 数据库文件

6

 人人都是 DBA(VI)SQL Server 事务日志

7

 人人都是 DBA(VII)B 树和 B+ 树

8

 人人都是 DBA(VIII)SQL Server 页存储结构

9

 人人都是 DBA(IX)服务器信息收集脚本汇编

10

 人人都是 DBA(X)资源信息收集脚本汇编

11

 人人都是 DBA(XI)I/O 信息收集脚本汇编

12

 人人都是 DBA(XII)查询信息收集脚本汇编

13

 人人都是 DBA(XIII)索引信息收集脚本汇编

14

 人人都是 DBA(XIV)存储过程信息收集脚本汇编 

15

 人人都是 DBA(XV)锁信息收集脚本汇编

本系列文章《人人都是 DBA》由 Dennis Gao 发表自博客园个人技术博客,未经作者本人同意禁止任何形式的转载,任何自动或人为的爬虫转载或抄袭行为均为耍流氓。


http://www.niftyadmin.cn/n/1415626.html

相关文章

计算机系统操作包含关系,计算机操作系统复习题目(1)

27、相对于单一内核结构&#xff0c;采用微内核结构设计和实现操作系统具有诸多好处。但是&#xff0c;()并不是微内核的优势。(浙江大学2006) A.使系统更高效 B.想添加新服务时&#xff0c;不必修改内核C. 使系统更易运行在不同的计算机硬件平台上 D. 使系统更可靠 【答案】A【…

Tomcat优化详细教程

Tomcat是我们经常使用的 servlet容器之一&#xff0c;甚至很多线上产品都使用 Tomcat充当服务器。而且优化后的Tomcat性能提升显著&#xff0c;本文从以下几方面进行分析优化。 一、内存优化 默认情况下Tomcat的相关内存配置较低&#xff0c;这对于一些大型项目显然是不够用的&…

教你查找运行系统里低劣的SQL方法

查找运行系统里bad sql是一个古老的话题, 我们要根据自己的实际情况来分析。绝不能教条的运用下面介绍的这些方法。使用这些SQL语句时&#xff0c;会对系统表产生分组操作&#xff0c;当然也增大了系统的负载。建议大家在系统启动了一段时间后&#xff0c;在半夜负载较轻的时间…

BZOJ4892: [Tjoi2017]dna

BZOJ4892: [Tjoi2017]dna Description 加里敦大学的生物研究所&#xff0c;发现了决定人喜不喜欢吃藕的基因序列S,有这个序列的碱基序列就会表现出喜欢吃藕的性状。但是研究人员发现对碱基序列S,任意修改其中不超过3个碱基&#xff0c;依然能够表现出吃藕的性状。现在研究人员想…

软件测试缺陷 报告英文版,如何写一个完美的软件缺陷报告(Defect)

如何写一个完美的软件缺陷报告(Defect)发表于&#xff1a;2016-12-08来源&#xff1a;徐文作者&#xff1a;测试改进工场点击数&#xff1a;编写缺陷报告是测试人员的日常工作&#xff0c;好的缺陷报告能够让开发人员更容易理解&#xff0c;更快速的定位问题&#xff1b;不好的…

50种方法巧妙优化你的SQL Server数据库

查询速度慢的原因很多&#xff0c;常见如下几种&#xff1a;    1、没有索引或者没有用到索引(这是查询慢最常见的问题&#xff0c;是程序设计的缺陷)    2、I/O吞吐量小&#xff0c;形成了瓶颈效应。    3、没有创建计算列导致查询不优化。    4、内存不足  …

nginx实战七

Nginx优化-配置参数优化上 https://coding.net/u/aminglinux/p/nginx/git/blob/master/optimize/nginx_opt.md Nginx作为高性能web服务器&#xff0c;即使不特意调整配置参数也可以处理大量的并发请求。 以下的配置参数是借鉴网上的一些调优参数&#xff0c;仅作为参考&#xf…

SQL取出 所有周六 周日的日期

SQL取出 所有周六 周日的日期 create table SatSun([id] int identity(1,1),[date] datetime,[weekday] char(6)) go declare datetime datetime,weekday char(6) set datetime2007-1-1 while datetime<2007-12-31 begin select weekdaydatename(weekday,datetime) if weekd…