经过DMV查看当时SQL SERVER全部任务的状态(sleeping、runnable或running)
200五、2008提供了如下三个视图工详细查询:
DMV
用处
Sys.dm_exec_requests
返回有关在SQL Server中执行的每一个请求的信息,包括当前的等待状态
Sys.dm_exec_sessions
对于每一个经过身份验证的会话都返回相应的一行。此时图是服务器范围的视图。此视图首先能够查到服务器负荷
Sys.dm_exec_connections
返回与SQL Server 实例创建的链接有关的信息以及每一个链接的详细信息
Sys.sysprocesses是为了向后兼容,因此建议使用以上3个DMV。
另外还有一个DMV:sys.dm_os_wait_stats能够返回从SQL Server启动以来全部等待状态的等待数和等待时间。是个累积值。
一、 LCK_XX类型:
若是SQL Server常常有阻塞发生,会常常看到以“LCK_”开头的等待状态:
等待状态
说明
LCK_M_BU
正在等待获取大容量更新锁(BU)
LCK_M_IS
等待获取意向共享锁(IS)
LCK_M_IU
等待获取意向更新锁(IU)
LCK_M_IX
等待意向排它锁(IX)
LCK_M_RIn_NL
等待获取当前键值上的NULL锁以及当前剪和上一个键之间的插入范围锁
LCK_M_RIn_S
等待获取当前键值上的共享锁以及当前键和上一个键之间的插入范围锁
LCK_M_RIn_U
等待获取当前键值上的更新锁以及当前键和上一个键之间的插入范围锁
LCK_M_RIn_X
等待获取当前键值上的排他锁以及当前键和上一个键之间的插入范围锁
LCK_M_RS_S
等待获取当前键值上的共享锁以及当前键和上一个键之间的共享范围锁
LCK_M_RS_U
等待获取当前键值上的更新锁以及当前键和上一个键之间的共享范围锁
LCK_M_RX_S
等待获取当前键值上的共享锁以及当前键和上一个键之间的排他范围锁
LCK_M_RX_S
等待获取当前键值上的共享锁以及当前键和上一个键之间的排他范围锁
LCK_M_RX_U
等待获取当前键值上的更新锁以及当前键和上一个键之间的排他范围锁
LCK_M_RX_X
等待获取当前键值上的排他锁以及当前键和上一个键之间的排他范围锁
LCK_M_S
等待获取共享锁
LCK_M_SCH_M
等待架构修改锁
LCK_M_SCH_S
等待获取架构共享锁
LCK_M_SIU
等待共享意向更新锁
LCK_M_SIX
等待获取共享意向排他锁
LCK_M_U
等待更新锁
LCK_M_UIX
等待更新意向排他锁
LCK_M_X
等待排他锁
二、 PAGEIOLATCH_X与WRITELOG:
在缓存池中的数据页面,为了同步多用户并发,SQL Server会对内存的页面加锁。不一样的是,加的是latch(轻量级的锁),而不是lock。
若是发生PAGEIOLATCH类型的等待时,SQL Server必定是在等待某个I/O动做的完成。若是常常出现这类等待,说明磁盘速度不能知足要求,已经成为SQL Server的瓶颈。
PAGEIOLATCH_X最多见的分两大类:PAGEIOLATCH_SH和PAGEIOLATCH_EX,PAGEIOLATCH_SH:常常发生在用户正想要访问一个数据页面,而同时SQL Server却要把页面从磁盘读往内存。说明内存不够大,触发了SQL Server作了不少读取页面的工做,引起了磁盘读的瓶颈。此时是内存有瓶颈。磁盘只是内存压力的副产品。
PAGEIOLATCH_EX:常常发生在用户对数据页面作了修改。SQL Server要向磁盘回写的时候。意味着写的速度跟不上。这和内存没直接关系。
WRITELOG:和磁盘有关的另外一个等待状态,正在等待写日志记录,意味着写入速度也明显跟不上。
三、 PAGELATCH_X:SQLServer为了解决在插入数据时,到了物理层的插入冲突,因此引入了另外一类页面上的latch:PAGELATCH,当一个任务要修改页面时,它必须先申请一个EX的latch。只有获得这个,才能修改页面的内容。因为数据页的修改都是在内存中完成,因此时间应该很是短,能够忽略不计。而PAGELATCH只是在修改过程当中才出现,因此生存周期应该很短,若是出现了,说明:一、SQLServer没有明显的内存和磁盘瓶颈。二、应用程序发来大量的并发语句在修改同一张表。而设计及用户业务逻辑使得这些修改都集中在同一个页面,或者数量很少的几个页面,成为Hot Page,一般在OLTP系统上出现比较多。三、这种瓶颈没法经过提升硬件配置解决,只能经过修改表设计或者业务逻辑,让修改分散,提升并发性。
对于Hot page的缓解方法:
(1)、换一个数据列建汇集索引,而不要在Identity的字段上,同一时间插入有机会分散到不一样的页面上。
(2)、若是必定要在Identity的字段上建汇集索引,建议在其余某个列上建若干个分区。
四、 Tempdb上的PAGELATCH:
数据库不只在数据页面修改的时候加latch,在数据文件的系统页面上,例如SGAM、PFS和GAM页面发生修改的时候,也会加latch。有时候也会成为系统瓶颈。
在建立新表须要分配空间时,SQLServer同时要修改SGAM、PFS和GAM页面,把已分配的页面标志成已使用,因此这些页面都会有所修改。但在tempdb中,这种操做会并发、反复。数据页的hot能经过调整表设计来缓解。对此的解决方法:
一、 创建与cpu数量相同的tempdb文件,而且大小要相同,这样能平均分配压力。
二、 严格防止tempdb空间用尽。防止自动增加时把其中一个文件增加,破坏平均分配。
三、 可使用sp_helpfile来查看文件信息。
五、 其余资源等待:
一、 LATCH_X:
(1)、某个先前的任务出现了访问越界异常,SQLServer强制终止了任务,可是没有彻底将它申请的资源释放干净。使其成为孤儿。后面的资源就被阻塞。只要打开SQLServer日志文件(errorlog),看看有没有出现过Access Violation问题,可是通常没法从用户层面通常没法解决,只有重启服务器才能解决。
(2)、同时发生其余资源瓶颈,如内存、线程调用、磁盘等,而latch等待只是一个衍生的等待。
(3)、当某个数据文件空间用尽,作自动增加的时候,同一个时间点只能有一个用户任务能够作文件自动增加动做,其余任务必须等待。
(4)、在一些特殊状况下,有多是SQLServer本身没有处理好并发同步,没有使用比较优化的算法,使得用户比较容易遇到等待,一些补丁就曾修复过这类问题。
通常等待都是由其余问题衍生出来,首先要检查SQLServer是否健康运行。是否有出现过任何异常。是否有其余资源瓶颈。
二、 ASYNC_NETWORK_IO(NETWORK_IO:2000的叫法):
此等待状态出如今SQLServer已经把数据准备好,可是网络没有足够的发送速度跟上,因此SQLServer的数据没地方存放。
(1) 出现这种状况通常不是数据库的问题,调整数据库配置不会有大的帮助。
(2) 网络层的瓶颈固然是一个可能的缘由:对此要考虑是否真有必要返回那么多数据?
(3) 应用程序端的性能问题,也会致使SQLServer里的ASYNC_NETWORK_IO等待。若是见到了这个类型的等待,就要检查应用程序的健康情况,也要检查应用是否有必要想SQLServer申请这么大的结果集。
三、 和内存有关的等待状态:
当用户任务申请内存暂时申请不到的时候,会出现一些特殊的等待状态:
COEMTHREAD/SOS_RESERVEDMEMBLOCKLIST/RESOURCE_SEMAPHORE_QUERY_COMPLIE
若是在DMV上看到这些状态,就要确认SQLServer是否存在内存瓶颈。
四、 SQLTRACE_X:
对于繁忙的SQLServer,开启SQL Trace会产生负面影响。若是出现这种等待,除非无可奈何,否则应该马上中止搜集SQL Trace
六、 最后一道瓶颈:许多任务处于runnable状态:
若是出现这种状态,证实不少任务能够运行但没在运行。
Sys.dm_exec_requests/sys.sysprocesses的status列,反映了当前全部任务的状态,若是看到好多状态是runnable,那就要严肃对待,正常的SQLServer哪怕很是忙,也不该该常常看到runnable,连running的状态都不该该不少。
若是没有报17883/17884之类的警告,出现很是多的runnable任务可能有两种缘由:
(1)、SQLServer CPU使用率接近100%,真的没有足够的cpu来及时处理用户的并发任务。此时应该优化最耗CPU资源的语句或者应用,或者加CPU
(2)、SQLServer CPU使用率并不高,小于50%。这时检查sys.dm_exec_requests的task_state列,会发现不少runnable状态。由于SQLServer除了lock和latch以外,还有一种更轻量级的同步资源:spin lock(自旋锁)。自旋:一些不会发生长时间等待的同步资源,SQLServer会选择让线程在cpu上稍微等待一下,而不会将cpu资源让出来。
可使用DBCC SQLPERF(SPINLOCKSTATS)查看。
在2005上的64位SQLServer,当内存比较充裕时,会缓存不少执行计划,同事缓存不少执行计划安全上下文。在memory clerk里,用TokenAndPermUserStore表示,当这段内存比较大时,并发用户会容易遇到一种叫MUTEX的自旋锁。能够参考:http://suppot.microsoft.com/kb/927396。这种问题只在安全上下文缓存得太多时才容易发生,因此按期执行一下如下语句有效防止,并且对系统总体性能也没什么坏的影响:
DBCC FREESYSTEMCACHE(TokenAndPermUserStore)
也能够以-T4618和-T4610启动SQLServer,让SQLServer使用另外一种缓存管理机制。
听说2008已经改进,不容易出现自旋锁。
七、 小结:
用户请求的什么周期:
一、 客户端向SQLServer发出请求指令,通过网络层,SQLServer接收到。
在这一步中,若是指令比较长,或者比较多,会影响SQLServer接受的速度。
二、 SQLServer对收到的指令进行语法、语义检查,编译,生成新的执行计划,或者找到缓存的计划重用:这一步耗费资源的种类比较多:
l CPU:作检查、编译、生成计划都须要计算,这一步耗费CPU资源比较多,尤为是指令复杂的时候。
l 内存:对于很是长的IN子句或者由几万、几十万语句组成,要花费很是大的内存,主要使用stolen内存,对于32位系统来讲是很紧张的。通常会出现这些等待状况:CMEMTHREAD/SOS_RESERVEDMEMBLOCKLIST/RESOURCE_SEMAPHORE_QUERY_COMPILE,或者701错误。
l 表上的架构锁(schema lock):在编译时,要防止对该架构进行修改。若是并发很高,那么会产生阻塞。
l 在SQLServer确认是否有线程的执行计划可用时,要在内存中进行搜索。可能会产生自旋锁。
三、 运行指令:
在等到执行计划以后,就进入运行阶段,用到的资源最多。在这一步要作不少事情:
(1) 、SQLServer首先为指令的运行申请内存。
若是同时须要执行不少指令,可能会在内存上遇到困难,一般会见到:RESOURCE_SEMAPHORE_开头的等待状态。
(2) 、若是发现要访问的数据不在内存中。
要讲数据从磁盘读到内存,若是发现内存没有足够的空闲页面存放全部数据,还要作内存整理和paging动做,腾出足够的空间放数据。一般简单的等待状态是:PAGEIOLATCH_X。
(3) 、按执行计划,扫描或者seek内存中的数据页面,讲执行须要处理的记录找出来。这一步须要申请各类各样的锁,以实现事务隔离。一般会引发阻塞,以LCK_开头的那些。
(4) 、指令可能还要作一些链接或者计算工做(sum、max、sort等)
这一步主要使用CPU。
(5) 、根据指令内容、执行计划和数据量,SQLServer可能还会在tempdb建立一些对象,存放临时表、表变量,帮助作join、sort等。
此时有可能出现tempdb瓶颈。
(6) 、若是指令须要修改数据记录,SQLServer会修改内存缓冲区里的页面内容。
因为对象在内存中,不会触发磁盘写入,但因为修改同一页面,容易致使PAGELATCH_X的等待状态。
(7) 、若是指令发生数据修改,在提交事务以前,SQLServer必须将相应的日志记录按照顺序写入日志文件。若是瞬间日志量太大,会出现WRITELOG的等待状态。
(8) 、将结果集返回给客户端:获得结果后,SQLServer会把结果集放到输出缓存中,等客户端把结果集所有取走。指令才结束。若是数据集太大,会致使网络交互太多。此时容易出现:ASYNC_NETWORK_IO等待状态。
以上的动做都要在SQLOS中首先获得一个Worker/thread,而后还要排上scheduler,在CPU上运行。
l SQLServer全部的Worker都在忙本身的事情,就会等待,能够看到等待状态是0x46(UMSTHREAD)。而sys.dm_os_schedulers.work_queue_count的值会不等于0
l 成功拿到worker,但在scheduler又要等待其余Worker,这时看到状态是runnable,而sys.dm_os_schedulers.runnable_tasks_count>1。
l 拿到scheduler,进入running状态,若是很是耗CPU,会出现cpu使用率高的现象。
l 遇到性能问题,查看sys.dm_exec_requests这类DMV对找到问题颇有帮助。
---------------------
做者:發糞塗牆
来源:CSDN
原文:https://blog.csdn.net/dba_huangzj/article/details/7607844
版权声明:本文为博主原创文章,转载请附上博文连接!算法