sys.dm_os_waiting_tasks 引发的疑问(中)
上一篇我们说了一下sys.dm_exec_requests 和 sys.dm_os_waiting_tasks 在获取并行等待的时候得不同结果,这一篇我们谈论下我的第二个疑问:为什么一个并行计划(4线程)却一下出现了那么多等待,SQL的并行到底是怎么执行的!!!!
先贴以下上篇sys.dm_os_waiting_tasks 的结果图:
我们分析一下这个结果的task_address 可以看出去掉重复其实只有9个,也就是说一个并行(4线程,配置不同,情况也不同)会有9个task。 又是线程,又是task ,还有worker,schedulers 这些都是什么? 这个有必要先说一下,因为这篇博客前我也是乱乱的。
scheduler
对于每个逻辑CPU,SQLSERVER会有一个scheduler与之对应,在SQL层面上代表CPU对象,只有拿到scheduler所有权的任务worker才能在这个逻辑CPU上运行
所谓逻辑CPU,就是SQLSERVER从Windows层面上看到的CPU数目,如果是一个双核的CPU,那么一个物理CPU在SQL看来就是两个逻辑CPU。如果系统还使用了
超线程hyper-threaded ,那对SQLSERVER来讲就是4个逻辑CPU
规则: 每个scheduler上的最大worker数目等于SQLSERVER的最大线程数除以scheduler的数目 ,在同一个时间点,只能有一个拥有scheduler的worker处于运行
状态,其他worker都必须处于等待状态。这样能降低每个逻辑CPU上的处于正在运行状态的线程数目,降低context switch,提供可扩展性
scheduler是SQLSERVER的一个逻辑概念,他不与物理CPU相绑定。也就是说,一个scheduler可以被Windows安排一会儿在这个CPU上,一会儿在那个CPU上。
但是,如果在sp_configure里设置了CPU affinity mask,那么scheduler就会固定在某个特定的CPU上
worker
每个worker跟一个线程(或纤程fiber)相对应,是SQLSERVER任务的执行单位。SQLSERVER不直接调度线程/纤程,而是调度worker,使得SQLSERVER能够控制
任务调度
规则: 每个worker会固定代表一个线程(或纤程),并且和一个scheduler相绑定。如果scheduler是固定在某个CPU上的(通过设置CPU affinity mask),那么
worker也会固定在某个CPU上
每个scheduler有worker的上限值,并且可以根据SQLSERVER工作负荷创建或释放worker,每次worker都会去运行一个完整的任务(task)。在任务做完之前不会
退出,除非这个任务主动进入等待状态。
scheduler只在有新任务要运行,而当前没有空闲的worker的情况下,才会创建新的worker。
某个worker空闲超过15分钟,scheduler可能会删除这个worker,以及其对应的线程。当SQLSERVER遇到内存压力的时,也会大量删除处于空闲状态的worker,以
节省multi-page的内存开销
各种CPU和SQLSERVER版本组合自动配置的最大工作线程数
CPU数 32位计算机 64位计算机
<=4 256 512
8 288 576
16 352 704
32 480 960
task
在worker上运行的最小任务单元。最简单的task就是一个简单batch。例如,客户发过来下面的请求:
1 SELECT @@SERVERNAME
2 GO
3 SELECT GETDATE()
4 GO
那么这两个batch就分别是两个task。SQLSERVER会先分配给第一个batch(select @@servername)一个worker,将结果返回给客户端,再分配第二个batch
(select getdate())一个worker。这两个worker可能是不同的worker,甚至在不同的scheduler上
只要一个task开始运行,他就不会从这个worker上被移出。例如,如果一个select语句被其他连接阻塞住,worker就不能继续运行,只能进入等待状态。但是这个
select task 不会将这个worker释放,让他做其他任务。所以结果是这个worker所对应的线程会进入等待状态
yielding
SQLOS的任务调度算法的核心,就是所有在逻辑scheduler上运行的worker都是非抢占式的 (non-preemptive)。worker始终在scheduler上运行,直到他运行结束,或者主动将scheduler让出给其他worker为止。这个“让出”scheduler的动作,我们叫yieding
每个scheduler都会有一个runnable列表,所有等待CPU运行的worker都会在这个列表里排队,以先进先出的算法,等待SQL分配给他scheduler运行
SQLSERVER定义了很多yieding的规则,约束一个task在scheduler运行的时间。如果task比较复杂,不能很快完成,会保证task在合适的时间点做yieding,不至于占用scheduler太多时间。
常见时间点:
1、当worker每次要去读数据页的时候,SQLSERVER会检查这个worker已经在scheduler上运行了多久,如果已经超过4ms,就做yielding
2、每做64KB的结果集排序,就会做一次yielding
3、在做语句编译compile的过程中(这个过程比较占CPU资源),经常会有yieding
4、如果客户端不能及时把结果集取走,worker就会做yieding
5、一个batch里的每一句话做完,都会做一次yieding
正常来讲,哪怕一个task要做很久,他使用的worker是会经常做yieding的,不会长时间占用CPU不放。如果在一个scheduler上同时有很多worker要运行,
SQLSERVER通过worker自动yielding的方式调度并发运行。这个比Windows用上下文切换context switch更有效
另附一张手绘图
另外推荐一篇 SQL SERVER SQLOS的任务调度 微软亚太的官方博客
-------------------------------------------------------------------------------------------------KK-------------------------------------------------------------------------------
我们大概了解了一下SQL SERVER SQLOS的任务调度 我们回到我们的并行话题看一下这个并行执行的调度情况:
一个并行处理分配给了9个task,同时也启用了9个worker,由4个scheduler调度,每个scheduler分别由一个申请数据,另一个等待。那么申请数据的是可以理解的,等待的是干什么的呢?个人理解和当前的执行计划有关,4个线程取得数据后要做汇总的操作SQL不会等待数据获取以后再开启线程接收,而是接收线程在获取数据的时候等待。
------------------------------------------------------------------华丽的分割线------------------------------------------------------------------------------
疑问得到解决了么?因为已经标记为中篇,可见还是有疑问呀!!!!我们继续下一篇吧....
本篇内容均为自己的理解,如有错误请大神们及时指出!!谢谢
sys.dm_os_waiting_tasks 引发的疑问(中)的更多相关文章
- sys.dm_os_waiting_tasks 引发的疑问(上)
很多人在查看SQL语句等待的时候都是通过sys.dm_exec_requests查看,等待类型也是通过wait_type得出,sys.dm_os_waiting_tasks也可以看到session的等 ...
- sys.dm_os_waiting_tasks 引发的疑问(下)
前面写了两篇了,其实不光是说sys.dm_os_waiting_tasks的应用,研究了挺长时间的并行,自己有了一些理解,所以分享出来希望有什么理解错误的地方大神们及时纠正!! 给出前两篇的连接: 上 ...
- 由一次PasswordBox密码绑定引发的疑问 ---> WPF中的附加属性的定义,以及使用。
1,前几天学习一个项目的时候,遇到了PasswordBox这个控件,由于这个控件的Password属性,不是依赖属性,所以不能和ViewModel层进行数据绑定. 2,但是要实现前后端彻底的分离,就需 ...
- 在Arrays.asList()引发的问题中进一步学习集合与泛型等内容
前言 最近在网上看到一个问题,情况类似如下(记为问题1): public class Demo { public static void main(String[] args) { System.ou ...
- 由一个项目需求引发的 - textarea中的换行和空格
当我们使用 textarea 在前台编辑文字,并用 js 提交到后台的时候,空格和换行是我们最需要考虑的问题.在textarea 里面,空格和换行会被保存为/s和/n,如果我们前台输入和前台显示的文字 ...
- 由命名空间函数而引发思考--js中的对象赋值问题
最近没有编码任务,作为一个才毕业的小辣鸡,给的任务就是看一下公司的新系统,熟悉怎么用哪些地方是干什么的. 下午喝了两杯水,感觉有点浪.然后就开始看了下代码.发现有一个函数是这样子的. var TX = ...
- 从一个LocalDateTime引发的疑问
一 公司有同事部署出错,然后查日志,找时间,从k8s得到的时间是 2017-06-16T09:38:48.580 +0000,然后他就纳闷了,因为他根本不会在9点部署好吧,而且9点大多数程序员都没开 ...
- Expert 诊断优化系列------------------语句调优三板斧
前面三篇通过CPU.内存.磁盘三巨头,讲述了如何透过现在看本质,怎样定位服务器三巨头反映出的问题.为了方便阅读给出链接: SQL SERVER全面优化-------Expert for SQL Ser ...
- SQL语句调优三板斧
改装有顺序------常开的爱车下手 你的系统中有成千上万的语句,那么优化语句从何入手呢 ? 当然是系统中运行最频繁,最核心的语句了.废话不多说,上例子: 这是一天的语句执行情况,里面柱状图表示的是对 ...
随机推荐
- is和as
一.明确两个基本概念 隐式转换: a.对于值类型,低精度=>高精度.eg:int=>long b.对于引用类型,子类向祖宗类转换过程.eg:对象=>Object 显式转换:显示转换是 ...
- java运行时获得泛型类型
引言 众所周知,java泛型最重要的特征是泛型擦除,所有泛型在编译时会转换成Object所以在java中运行时无法获得泛型的类型. 但是其实以上的规则是针对方法的内部变量的,如果是其他形式的泛型其实是 ...
- Android开发学习之路-插件安装、检查应用是否安装解决方案
使用Bmob的时候,如果需要用到支付功能,就需要让应用去安装一个支付插件.而一般的做法是将插件放置在assets目录中,当用户需要支付,先检查是否能支付,不能的话,提示安装插件.代码: public ...
- salesforce 零基础学习(六十一)apex:component简单使用以及图片轮转播放的实现
有的时候,我们项目有可能有类似需求:做一个简单的图像轮转播放功能,不同的VF页面调用可以显示不同的图片以及不同的图片描述.这种情况,如果在每个页面单独处理相关的图像轮转播放则显得代码特别冗余,此种情况 ...
- PHP_02之使用补充
JSON字符串在项目中的应用: ①PHP服务器给客户端JS发送JSON响应数据: PHP: $arr=[...]; echo json_encode($arr); JS: var ob ...
- 在thinkPHP3.2.3框架下实现手机和PC端浏览器的切换
查看thinkphp版本号方法 打开文件“根目录\ThinkPHP\ThinkPHP.php”下的文件ThinkPHP.php,在22--23行可以看到版本信息THINK_VERSION,如下图: 说 ...
- ★Kali信息收集~★7.FPing :ip段扫描
参数: 使用方法: fping [选项] [目标...] -a显示是活着的目标 -A 显示目标地址 -b n 大量 ping 数据要发送,以字节为单位 (默认 56) -B f 将指数退避算法因子设置 ...
- CSS系列目录
1. 在HTML中引入CSS的方法 2. CSS选择器 2.1 CSS3新增选择器 3. CSS的继承与层叠特性 4. CSS中盒子模型 5. CSS中盒子之间的关系 6. CSS中盒子的 ...
- ASP.NET中Session的sessionState 4种mode模式
1. sessionState的4种mode模式 在ASP.NET中Session的sessionState的4中mode模式:Off.InProc.StateServer及SqlServer. 2. ...
- iOS 调试工具
仪表 xcode5 引入了调试仪表,通过仪表可以直观的看出应用的CPU和内存占用量.运行一个程序,点击仪表栏.可以发现当程序处于运行状态时,调试导航面板会以柱状图显示CPU和内存占用量,并随着应用实 ...