数据库引擎-线程和任务

每个数据库实例都是一个独立的操作系统进程。每个进程可能同时服务于上千个连接,每个连接都需要一个或多个线程来接受请求,处理并返回结果。此外,数据库进程还需要线程维护网络通讯的线程,各个服务之间进行通讯的线程。

 

数据库是如何调度这些线程呢?

数据库实例有自己的调度机制,这样当需要线程调用时,它就不需要访问系统内核。它通常维护一个线程缓冲区,因此它不需要进行太多的创建或销毁的操作。可以通过max worker threads来限制缓冲区的大小。当用户请求道来时,如果有空闲的线程,则直接调用;如果没有,但没有到达最大限制,则创建;否则等待。通常它不会删除缓冲池中的线程。

 

这些线程是如何协作完成用户请求的呢?

首先,为了访问数据库,必须要建立连接,通过连接可以发送多个查询语句组成一个包。数据库为每个连接分配一个会话ID,SPID,并维护一个相关的内部数据结构。当一个包到达数据库以后,会被分解成若干任务。然后每个任务会被一个工作线程完成。这个工作线程可以是一个普通的系统线程,也可以是一个数据库所专有的特殊线程。

 

线程和CPU?

由于操作系统是真正控制CPU等资源的地方,因此数据库的线程最终必须映射到操作系统上,然后分配到某个CPU上。可以通过affinity mask来控制是否将某个数据库实例的线程分配到某个CPU上。如果机器上有4个CPU,那么0010的掩码值表示该实例的所有线程只在第二个cpu上。

 

线程的优先级?

windows对线程分配了31个优先级别。通常数据库的线程优先级是7,它足以获取需要的资源,但又不会恶意抢占别的线程的资源。可以通过priority boot提高线程优先级,但这样就意味着别的应用程序会被数据库剥脱资源而变慢,即使数据库被IO操作所阻塞,别的应用也很难获得CPU时间。因此该选项仅用于非常时刻。

 

最后可以通过 sys.dm_os_tasks 来查看当前的数据库实例中有多少个正在执行的任务,如下面的SQL返回当前会话正在执行的任务:

select * from sys.dm_os_tasks where session_id=@@spid

通过它返回的结果可以在视图sys.dm_os_workers 中找到与它相关联的工作线程地址;

再通过sys.dm_os_threads找到相应的工作线程。

通过最后一个view可以知道某个线程所花费的资源,如CPU时间,使用stack的量等。

还可以判断某个线程是否被阻塞。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值