zoukankan      html  css  js  c++  java
  • SQL Server OS 调度

    --SQL SERVER OS 采用合作模式的线程调度模式,即除非Worker主动放弃CPU,否则SQL OS 不会强制剥夺其CPU,从而减少Context Switch

    --默认设置下,SQL SERVER 创建与逻辑CPU数量相同的Scheduler,但Scheduler并不与CPU硬性绑定直到DBA指定Process Affinity,通过配置Process Affinity(修改关联掩码)来使指定CPU对应的Scheduler离线或联机。

    --当特定Scheduler修改为离线时,会将该Scheduler转移到其他CPU上,并阻止为其再分配Worker,当该Scheduler上所有Worker执行完毕后,Scheduler转为离线。

    --在负载严重或Scheduler被离线时,一个CPU可能对应多个Scheduler

     

    --可以使用以下代码来查看

    SELECT * FROM sys.dm_os_schedulers S

    WHERE S.scheduler_id<255

    --对于大于的Scheduler用于系统专用,如死锁检测,CheckPoint, LazyWriter

    --SQL SERVER,Scheduler并不直接调用线程处理,而是使用Worker 来承载负载,在特定时刻,一个Scheduler上只能有一个Worker处于运行状态。随着数据库的负载变化,SQL Server会增加或释放Workder

    --默认设置下,Worker的最大数量有SQL Server进行管理,取决于SQL Server32位还是64位以及SQL Server使用的CPU数量,DBA也可手动配置Workd的最大数量。

    --Worker空闲超过15分钟或系统面临内存压力时,SQL Server会尝试释放Worker来回收内存,在32位系统下,每个Worker至少占用0.5MB内存,在64位系统下,每个Worker至少占用2MB内存。

    --对于每个Scheduler,会有一字段load_factor来表示scheduler的繁忙程度,从而动态地将新Worker分配给负载最小的Scheduler,但对于同一个连接,SQL Server会记住该连接最后一个worker使用的scheduler_id,并尽可能为该连接上后续的worker分配给同一个scheduler(为了减小查找最小负载scheduler的开销),但如果该scheduler上负载大于所有scheduler负载平均值的20%SQL Server会为新worker分配负载最低的scheduler

    --为提升效率和节约资源,SQL Server使用Worker pool来存放创建的worker,提高其重用率。

    --TaskSQL Sever 调度管理器中最小的任务单元,运行于Workder之上,只有获取WorkerTask才能运行。

    --对于同一连接发送来的多个BacthSQL Sever倾向于交给同一个Task来处理,但也可能交给不同的Worker,运行在不同的schduler上。

    --由于SQL Server使用合作的线程调度模式,如果某一个Worker长期占用scheduler就会导致该scheduler上其他runableworker长时间得不到运行,因此需要SQL Server根据一定策略来将该worker切换出来让其他worker得以运行。Worker切换出来的过程称之为yieldyield可大致分为两种:

    1. worker在运行中需要等待获取其他资源而被造成阻塞,在阻塞发生时却换,称为natual yield

    2. worker在长时间运行或某个阶段结束时发生却换,称为voluntarily yield

    --voluntarily yield便是SOS_SCHEDULER_YIELD等待的原因,发生这类yield的场景:

    --基于时间片的voluntarily yield大概使得Worker每秒yield一次。这个值可以通过sys.dm_os_schedulersquantum_length_us列看到。

    --64K结果集排序,就做一次yield

    --语句complie,会做yield

    --读取数据页时

    --batch中每一句话做完,就会做一次yield

    --如果客户端不能及时取走数据,worker也会做yield

    在高并发下,需要worker频繁地从running状态却换到waiting状态,以实现各请求的快速响应,每次却换即一次switch.

    --如果Worker需要运行一些抢占式的代码,则该worker不能再由SQL OS来控制,而需要转交给Windows任务调度系统来控制,当Worker上抢占式的task运行结束后再交给scheduler来控制。

    --等待类型中"PREEMPIVE_*"的等待便是由抢占式Task所造成的,该类task包括扩展存储过程+windows API调用+日志填0初始化等

    SQL OS使用Worker自己yield的方式来实现context switch,该switch提升了并发性,同时与windows的线程switch相比又减少了资源开销。

    参考:

    1.SQL SERVER 2005技术内幕:存储引擎

    2.http://www.cnblogs.com/CareySon/archive/2013/02/01/SqlOSSchedule.html

  • 相关阅读:
    H5新增——html概述
    H5新增———html5概述
    ASP.NET Web API Demo OwinSelfHost 自宿主 Swagger Swashbuckle 在线文档
    如何写个死循环,既不独占线程,又不阻塞UI线程?
    C# 扩展TaskScheduler实现独立线程池,支持多任务批量处理,互不干扰,无缝兼容Task
    C# async await 异步执行方法封装 替代 BackgroundWorker
    巨坑!
    C# .NET Socket SocketHelper 高性能 5000客户端 异步接收数据
    一个简单的例子看明白 async await Task
    一个非常轻量级的 Web API Demo
  • 原文地址:https://www.cnblogs.com/TeyGao/p/3313718.html
Copyright © 2011-2022 走看看