所谓整体架构,这里是指SQL Server数据库系统正常工作和运行所必备的组件及其机制。整体上来讲,这主要包括实例(Instance)和数据库(Database)。在此基础上再进一步划分,实例由服务器上的相关内存区域和服务线程组成;数据库包括操作系统上的各种相关文件。上述相关内存区域、服务线程及文件又可再进一步细分。下面就按照这个顺序和逻辑,逐步讲解SQL Server数据库系统的整体架构。


1.  实例


实例,即数据库实例,由服务器上的一组内存结构和线程(因为SQL Server for Windows为线程模型,另外,因本书基于SQL Server 2012+ for Windows创作编写,通篇将其统称为SQL Server,不再赘述)组成,用以支撑和完成数据库的正常运行和操作,其主要包括以下组件。

1.1. 内存(Memory)

服务器操作系统为实例分配的内存区域,用于数据库内存方面的活动和操作,主要分为三个部分:Buffer Pool、Query/Workspace Memory(本书通篇将其统称为Query Memory,不再赘述)和其他Cache。因为SQL Server为线程模型,整个实例通过Windows上一个进程实现,而Oracle则是通过诸多进程实现的进程模型(Oracle for Windows版本除外,本书中Oracle通篇均指for Windows外的版本,不再赘述),所以,SQL Server各内存区域与Oracle有所不同。SQL Server各内存区域,就其实现机制来讲,并没有共享和私有的区别和转换,而就其功能来讲,还是有共享和私有之分,Buffer Pool和其他Cache为实例共享,而Query Memory为会话私有。就实例各内存组件实现及功能来讲,SQL Server for Windows版本与Oracle for Windows版本还是更加相似。我们可以通过查询SQL Server目录视图(Catalog View)来查看内存相关信息。

select type,sum(pages_kb) from sys.dm_os_memory_clerks

group by type

order by sum(pages_kb) desc;

1.1.2. 后台线程(Background Threads)

实例创建、管理和维护的一组后台线程,用以完成数据库内部的各种管理和监控任务。线程的数量和名字随版本和具体配置的不同而有所不同,但这些线程是实例共享的,并不属于某个或某些会话,例如:Lazy writer,Eager writer,Checkpoint writer,Log writer,Signal handler,Task manager,Rerourse monitor等。我们可以通过查询SQL Server目录视图来获取后台线程的相关信息。

select t.os_thread_id,r.session_id,r.status,r.command
from sys.dm_os_threads t inner join sys.dm_os_workers w 
on t.thread_address=w.thread_address
inner join sys.dm_exec_requests r on w.task_address=r.task_address
where r.status like N'%background%';
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.

1.1.3. 服务线程(Server Threads)

实例为数据库会话创建或分配的,用以完成会话任务的服务器端服务线程(数据库层面也叫作Worker,本书通篇将统称为工作线程,不再赘述)。SQL Server的工作线程都是共享的,这点不同于Oracle的服务进程。Oracle中,根据配置的不同,服务进程可以分为专用模式和共享模式。我们可以通过查询SQL Server目录视图来查询工作线程的相关信息。

select t1.session_id,convert(varchar(10), t1.status) status,
convert(varchar(15), t1.command) AS command,  
        convert(varchar(10), t2.state) AS worker_state,  
        w_suspended =   
        case t2.wait_started_ms_ticks 
when 0 then 0  
        else   
          t3.ms_ticks - t2.wait_started_ms_ticks  
        end,  
        w_runnable =   
        case t2.wait_resumed_ms_ticks  
        when 0 THEN 0  
        else   
          t3.ms_ticks - t2.wait_resumed_ms_ticks  
        end  
  from sys.dm_exec_requests t1  
  inner join sys.dm_os_workers t2  
    on t2.task_address = t1.task_address  
  cross join sys.dm_os_sys_info t3  
  where t1.scheduler_id is not null
and t1.status  not like N'%background%';
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.

1.1.4. 调度线程(Scheduler Threads)

SQL Server实例中的工作线程是共享的,类似Oracle中服务进程的共享模式,然而,Oracle中有Dispatcher来为会话调度和分配服务进程,那么,SQL Server中,谁来为会话分配工作线程呢?因此,我们在这里就必须提到一个线程,那就是调度线程。

SQL Server中的每个工作线程都对应一个调度线程,其作用就是为每个工作线程分配CPU时间片。SQL Server实例中调度线程的数目为其可用逻辑CPU数加1,这个额外加上的一个调度线程用于专用管理员连接(Dedicated Administrator Connection,DAC)。

SQL Server 6.5及更低的版本,都一直是用Windows的基本调度器,该基本调度器不会对服务器上的任何应用有特殊照顾,也被称为抢占式调度器(Pre-emptive Scheduler),它会为每个在CPU上执行的任务分配称为量子(Quantums)的固定时间片,一旦被分配的时间片用光,该调度器将立刻中断该正在执行的任务,根本不会顾及该任务当前执行的时间点以及此时中断是否合适。该抢占式调度器的好处是应用开发者不用关心应用的调度问题,而缺点也是显而易见的,那就是在执行的任务也许在不合适的时间点被强行打断,让位给其他任务,等待自己下一个时间片的到来。

虽然SQL Server 6.5及更低版本一直使用Windows的基本调度器,但是在此期间,Windows开发组为了优化CPU的使用而付出了长期而不懈的努力,然而,SQL Server的扩展性及性能不可避免的越来越受到Windows基本调度器的严重限制。

终于,随着SQL Server 7.0版本的诞生,这一切都改变了,微软决定让SQL Server 7.0版本创建自己的用户模式调度器(User Mode Scheduler,UMS),并让它们来调度SQL Server的工作线程。由于这些调度器是应用内部的调度器,因此,它们不再是抢占式的调度器,而是合作式的调度器。

当SQL Server的工作线程在CPU上执行时,不会再被调度器强行中断,而是在合适的时机(例如:该工作线程接下来需要等待其他资源)自愿让出CPU供其他工作线程执行,这样,增强了各工作线程间的协作,也大幅提高了整个系统的性能和效率。我们可以通过目录视图来查看调度器相关的信息。

select * from sys.dm_os_schedulers order by scheduler_id;

--注:

      1)以上查询结果中,除了状态是“Visibe Online”的调度器外,还有状态是“Hiden Online”的调度器,前者用于用户任务的调度;后者用于SQL Server数据库引擎内部任务的调度。其中,“Online”意味着该调度器对应的CPU处于在线状态,而“Offline”则意味着该调度器对应的CPU处于离线状态。

1.1.5. SQLOS

既然前面谈到了调度器,那么,我们就有必要说一下SQLOS,起码,让大家对这些概念有一个透彻的了解和理解。

SQLOS最初出现于SQL Server 2005版本中,它把之前版本中所有低级操作(例如:调度,IO,内存管理,资源管理等)统统集中到一个地方来进行处理,这样,既节省了人力,使得之前部分研发人员腾出手来去做其他工作;也便于研发人员集中精力来不断改进和优化SQLOS功能,改变了此前相关功能研发分散和重复的局面;同时,集中式的SQLOS能更好的优化Windows及SQL Server性能。

此外,SQLOS也为用户提供了更便捷、更丰富的管理、查看和分析SQL Server的方法和途径,通过动态管理视图(DMVs),用户可以很方便的获取相关方面的大量信息。

1.1.6. 动态管理视图(DMVs)

动态管理视图(DMVs)是Dynamic Management Views的简称,其最早出现于SQL Server 2005版本中,其目的就是为了方便用户对SQL Server的管理和应用。DMVs本质是基于SQL Server内部系统表和内存系统计数器建立的一些视图,除了DMVs外,SQL Server还提供了动态管理函数(Dynamic Management Functions,DMFs),但一般将它们也统称为DMVs。

使用这些DMVs的语法是sys.dm_,后面紧跟想查询信息的相关区域,例如:SQLOS的相关DMVs为sys.dm_os_*,数据库的相关DMVs为sys.dm_db_*,查询执行相关的DMVs为sys.dm_exec_*等。