解析SQL Server之任务调度

摘要:
即,“SQLServer如何执行客户端输入的SQL语句?执行SQLServer架构逻辑的核心组件是SQLOS(简称SQL Server操作系统)?将语句提交给SQL Server服务引擎和查询引擎的命令处理器(QueryProcessor)首先,检查语法结构,命令分析器将转到缓冲池的计划任务,以查找语句缓存是否存在;然后命令分析器将计划缓存发送给查询执行器进行处理。

  在前面两篇文章中( 浅谈SQL Server内部运行机制 and 浅谈SQL Server数据内部表现形式 ),我们交流了一些关于SQL Server的一些术语,SQL Sever引擎

与SSMS抽象模型,SQL Server内部存储机制和SQL Server内部体系结构等。讨论的这些问题,均可以归为一个问题,即"SQL Server是怎么执行客户端输入的SQL

语句的?”,其中,重点讨论了下图(SQL Server 体系结构)

        解析SQL Server之任务调度第1张

       然而,如果我们仅仅了解如上技术,是不具备一个资深DBA或数据库优化高手条件的,原因很简单,我们仅仅知道了SQL Server是怎么做的(SQL Server是如

何执行SQL语句的),但是我们并不知到是什么做的(是什么真正执行SQL语句?),只知其然,而不知其所以然。本篇文章,我们将重点论述是什么执行了SQL Server

体系结构逻辑?其实,执行SQL Server体系结构逻辑的核心组件便是SQLOS(简称SQL Server操作系统)。

 一  SQL Server引擎组件


       下图为SQL Server引擎核心主件,它大致包括五大部分:协议层(Protocol Layer),查询引擎(Query Processor),存储引擎(Storage Engine),公用组件(Utilities)和

SQL Server操作系统(SQLOS)。其中,除了Utilities和SQLOS两大部分外,其他部分在前面两篇文章中均已简要论述。本篇文章,我们将重点论述SQLOS。

解析SQL Server之任务调度第2张

         (一)SQLOS

         SQLOS是SQL Server和Windows OS(Windows  操作系统)瘦用户模式层,它主要负责一些底层的操作,如调度、处理I/O、内存管理、文件管理等。

        当客户端(如在SSMS中输入)输入一条SQL语句(SELECT * FROM TableName),并基于TDS服务点,向SQL Server服务引擎提交该语句,SQL Sever引擎接收到

该语句后(准确来说,是先通过Protocol Layer协议层),查询引擎的命令分析器(Query Processor)先检查语法结构,若语法结构有错误,则直接将错误返回给客户端,

编译不通过;若语法正确,则命令分析器会去缓冲池的计划任务中寻找是否存在该语句的缓存,若存在,则命令分析器把该计划缓存交给查询执行器处理,若缓存池的计

划缓存中没有该计划任务,则命令解析器将会生成查询树,并将该SQL语句传递给查询优化器,查询优化器根据“最少开销算法”生成最优方案,然后传递给查询执行器;

流程到查询执行器后,查询执行器通过存储引擎的访问方法传递给存储引擎,存储引擎根据规则来配置和使用缓冲区管理器和事务管理器,接下来的工作,就交给

SQLOS来处理。

        也许读者会问?为什么不直接用Windos OS来调度,而要另做一个SQLOS来执行调度呢?因为Windows OS是基于“抢占式调度算法的”,这种算法依据时间片来执行的,

这种算法并没有针对SQL Server进行优化,为了解决这个问题,微软决定SQL Server应自己处理自己的调度,并通过创建用户模式调度器(UMS)来解决该问题,UMS基于

“合作调度模式”算法被设计,这种算法指当执行中的线程需要等待其他资源才能执行时,不会因为时间片的轮询被中断,而是采用自动退出处理器的方式。

      解析SQL Server之任务调度第3张

     (二)线程三态

       当在一个会话中执行请求时,SQL Server将这项工作(这个请求)分成一个或多个任务,每个任务由一个线程负责,任务被放在任务队列中,等待调度器去调度工作线程来执行,

原则上,调度器会为每个任务分配一个工作线程,这个工作线程就负责执行该任务。每个线程都有三个状态,即执行状态(Running)、挂起状态(Suspend)和可执行状态(Runable)。

  • 执行状态(Running):表示该线程正在执行任务       
  • 挂起状态(Suspend):表示该线程因缺资源,被CPU强制挂起,如尝试修改被锁的表
  • 可执行状态(Runnable):表示线程具备了可执行任务的条件,如线程1执行完任务1后,被放在线程队列中,等待调度器分配任务

     线程三个状态之间,存在如下转换关系:

      1.具备执行条件的线程(Runnable),只要获得CPU,就可执行任务,从而从Runnable状态变成Running状态

      2.正在执行的线程(Running)因缺必要资源,被cpu挂起,从而从Running状态变成Suspend状态

      3.被挂起的线程(Suspend)因获得可执行的资源,被cpu唤醒执行,从而从Suspend状态变成Running状态

      4.Runnable状态的线程,调度器可不让其执行(这里,暂且称之为Suspeng状态)

     解析SQL Server之任务调度第4张

      (三)Windows OS与SQL Server

       当一台电脑刚生产出来,未装任何系统时,我们称之为裸机,对于裸机,我们是无法使用的,若要使用,则需要安装操作系统,如win10,

当我们在裸机上装上操作系统后,就可以通过操作系统来操作电脑了,如查看cpu,管理文件,管理内存等,不仅仅如此,我们还在操作系统上

安装相应的运用软件,如Visual Studio 2017,SQL SERVER 2014等。

      解析SQL Server之任务调度第5张

二  SQL Server一个较为完整的调度流程


     当SSMS向SQL Server引擎发起请求时,将会产生一个会话(Session),会话成功后,就可以执行SQL语句请求了。

     1.当建立会话成功后,在会话中建立一个SQL语句请求时(如执行查询语句:SELECT * FROM TableName),会话会将一个请求分成一个或多个任务,并将这些任务放在任务队列中;

     2.每个任务都会被分配一个或多个工作线程来执行;

     3.SQLOS任务调度器通过从工作线程队列中调度线程来执行相应的工作任务

     注意:SQLOS只是逻辑的,真的的执行还是Windows OS

     以下是一些涉及到的相关类型表

      sys.dm_exec_*:该类型表包含用户代码执行和关联连接直接或间接相关的信息,如请求表sys.dm_exec_requests,会话表sys.dm_exec_sessions

      sys.dm_os_*:    该类型表包含操作OS相关的信息

      sys.dm_tran_*:  该类型表包含事务相关信息

      sys.dm_logpool_*:该类型包含日志相关信息

      sys.dm_io_*:      该类型表包含IO相关信息

      sys.dm_db_*:    该类型包含数据库相关信息

 解析SQL Server之任务调度第6张

三  参考文献


 【01】《Microsoft SQL Server 2012 Internals》Kalen Delaney,Bob Beauchemin,Conor Cunningham,Jonathan Kehayias,Benjamin Nevarez,Paul S.Randal

 【02】《Microsoft SQL Server 2012 Administration》Tom Carpenter

 【03】《SQL Server 2012 深入解析与性能优化 第3版》Christian Bolton,Justin Langford,Glenn Berry,Gavin Payne,Amit Banerjee,Rob Farley著

 【04】《Microsoft SQL Server 2008 技术内幕:T-SQL查询》ltzik Ben-Gran,Lubor Kollar,Dejan Sarka,Steve Kass著

 【05】《SQL Server 2008查询性能优化》Grant Fritchey,Sajal Dam著

转自:https://www.cnblogs.com/wangjiming/p/10175380.html

免责声明:文章转载自《解析SQL Server之任务调度》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇火星坐标、百度坐标、WGS-84坐标相互转换及墨卡托投影坐标转经纬度JavaScript版Python学习笔记:pd.rank排序下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Java中System.out.println()为何会影响内存可见性?

我们先来看段代码: 1 class ThreadVolatileDemo extendsThread{ 2 static boolean flag=true;//注意该变量没有被volatile修饰 3 @Override 4 public voidrun() { 5 while(flag){ 6 S...

Java-多线程第四篇线程池

1、什么是线程池。     线程池在系统启动的时候即创建大量的空闲的线程,程序将一个Runnable对象或者Callable对象传给线程池,线程池就会启动一个线程来执行它们的run()或者call()方法,当run()或者call()方法执行结束后,该线程并不会死亡,而是再次返回线程池称为空闲状态,等待执行下一个Runable对象的run()或者call(...

进程简述

简而言之,一个程序至少有一个进程,一个进程至少有一个线程. 线程的划分尺度小于进程,使得多线程程序的并发性高。另外,进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极大地提高了程序的运行效率。线程在执行过程中与进程还是有区别的。每个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口。但是线程不能够独立执行,必须依存在应用程序中,由应用程...

C# 线程手册 第二章 .NET 中的线程 终止/等待线程

Abort()方法可以用来终止当前线程。不论何种情况下你想终止线程,比如线程执行了太长时间或者用户取消了之前的决定,Abort()方法都很重要。在一个花费很长时间的搜索进程中你可能想使用这个方法。一个搜索引擎可能在继续运行但是用户已经看到了他们想要的结果,所以用户会终止搜索引擎所运行的线程。当在一个线程外调用Abort()方法时,会引发一个ThreadAb...

【转】DELPHI 线程类

原文地址:http://yyimen.blog.163.com/blog/static/179784047201211811178223/ Delphi中有一个线程类TThread是用来实现多线程编程的,这个绝大多数Delphi书藉都有说到,但基本上都是对TThread类的几个成员作一简单介绍,再说明一下Execute的实现和Synchronize的用法就...

[转]TestNG的多线程并行

前言 最近在做项目里的自动化测试工作,使用的是TestNG测试框架,主要涉及的测试类型有接口测试以及基于业务实际场景的场景化测试。由于涉及的场景大多都是大数据的作业开发及执行(如MapReduce、Spark、Hql等任务的执行),而这些任务的执行都需要耗费较多的时间。举一个普遍的例子,其中一条场景测试用例是: 执行一个MapReduce作业,校验作业的执...