数据库系统异常是DBA经常要面临的情景,一名有一定从业经验的DBA,都会有自己一套故障排查的方法和步骤,此文为为大家介绍一下通过系统

性能视图(SQLServer05以上版本)来排查系统异常的基本方法,希望能对大家有所帮助。

这里分两部分来介绍:

一.  从数据库连接情况来判断异常:

1. 首先我们来看一下目前数据库系统所有请求情况:

--request info
select s.session_id, s.status,db_name(r.database_id) as database_name,
s.login_name,s.login_time, s.host_name,
c.client_net_address,c.client_tcp_port,s.program_name,
r.cpu_time, r.reads, r.writes,c.num_reads,c.num_writes,
s.client_interface_name,
s.last_request_start_time, s.last_request_end_time,
c.connect_time, c.net_transport, c.net_packet_size,
r.start_time, r.status, r.command,
r.blocking_session_id, r.wait_type,
r.wait_time, r.last_wait_type, r.wait_resource, r.open_transaction_count,
r.percent_complete,r.granted_query_memory
from Sys.dm_exec_requests r with(nolock)
right outer join Sys.dm_exec_sessions s with(nolock)
on r.session_id = s.session_id
right outer join Sys.dm_exec_connections c with(nolock)
on s.session_id = c.session_id
where s.session_id >50
order by s.session_id

某台生产机运行情况:

这个查询将目前数据库中的所有请求都显示出来了,其中比较重要的有Status、Login_name、Host_Name,Client_Net_Address、Program_name

等,但是信息比较多,我们很难查看有什么异常,但是可以通过一图中红色圈的数字:441 初步判断连接数是否超过了平时的标准(很多时候系统异常是连接

数过多造成的,而连接数过多又是因为其他原因影响的)。

2. 哪个用户连接数最多:

--request info by user
select login_name,COUNT(0) user_count
from Sys.dm_exec_requests r with(nolock)
right outer join Sys.dm_exec_sessions s with(nolock)
on r.session_id = s.session_id
right outer join Sys.dm_exec_connections c with(nolock)
on s.session_id = c.session_id
where s.session_id >50
group by login_name
order by 2 desc

运行结果:

从图中我们可以很方便的看出用户连接数情况,如果我们的不同的功能是使用不同的的数据库账号的话,就能初步判断是哪部分功能可能出现了异常。

3. 哪台机器发起到数据库的连接数最多:

--request info by hostname
select s.host_name,c.client_net_address,COUNT(0) host_count
from Sys.dm_exec_requests r with(nolock)
right outer join Sys.dm_exec_sessions s with(nolock)
on r.session_id = s.session_id
right outer join Sys.dm_exec_connections c with(nolock)
on s.session_id = c.session_id
where s.session_id >50
group by host_name,client_net_address
order by 3 desc

运行结果:

这个查询能够一下就帮我们找出来哪些机器发起了对数据库的链接,它们的链接数量是否有异常;这个其实对调查某些问题非常有用,我有一次就遇

到一个case:

用户反映,过一两个星期,系统就会出现一次异常,出问题时数据库连接数量很高,大量的访问被数据库拒绝,过半个小时左右,系统又自动恢复了,但是

在数据库里面查看,并没有发现有异常的进程和错误的信息,问题一时很棘手,很难定位,系统不稳定领导不满,DBA顶着压力一时不知道如何是好;后面

转换方向,通过调查问题发生时,为什么会产生这么多连接,这些连接是那些机器发过来的,这些连接发过来正常吗,是数据库不砍业务的重负,还是业务

在某个时间段内会出现暴涨等一系列原因,最终找出是一台Web因为开发人员代码写的有问题,内存出现内存泄露,导致大量的连接不能释放,出问题是,

发出的数据库连接数比平时高3-4倍,最终影响到了数据库,问题压根和数据库没关系(从这个事实看出,DBA真是的炮灰角色,不是自己的问题,也得顶

着压力调查出原因呀);如果在类似问题发生时,我们能通过这个查询及早知道问题是出在某台Web机器上,那就不用费尽心力来调查数据库了。

4. 这些连接在访问哪个库:

--request info by databases
select db_name(r.database_id) as database_name,COUNT(0) host_count
from Sys.dm_exec_requests r with(nolock)
right outer join Sys.dm_exec_sessions s with(nolock)
on r.session_id = s.session_id
right outer join Sys.dm_exec_connections c with(nolock)
on s.session_id = c.session_id
where s.session_id >50
group by r.database_id
order by 2 desc

结果(为NULL的估计是没办法定位库):

5. 进程状态:

--request info by status
select s.status,COUNT(0) host_count
from Sys.dm_exec_requests r with(nolock)
right outer join Sys.dm_exec_sessions s with(nolock)
on r.session_id = s.session_id
right outer join Sys.dm_exec_connections c with(nolock)
on s.session_id = c.session_id
where s.session_id >50
group by s.status
order by 2 desc

结果(running数比较多,表面数据库压力比较大):

二. 从阻塞情况来判断异常(这部分内容不再一一贴图,直接上脚本):

1. 查看数据库阻塞情况:

----------------------------------------Blocked Info----------------------------------
--记录当前阻塞信息
select t1.resource_type as [lock type] ,db_name(resource_database_id) as [database]
,t1.resource_associated_entity_id as [blk object]
,t1.request_mode as [lock req] -- lock requested
,t1.request_session_id as [waiter sid] -- spid of waiter
,t2.wait_duration_ms as [wait time]
,(select text from sys.dm_exec_requests as r with(nolock) --- get sql for waiter
cross apply sys.dm_exec_sql_text(r.sql_handle)
where r.session_id = t1.request_session_id) as waiter_batch
,(select substring(qt.text,r.statement_start_offset/2,
(case when r.statement_end_offset = -1 then len(convert(nvarchar(max), qt.text)) * 2
else r.statement_end_offset end - r.statement_start_offset)/2+1)
from sys.dm_exec_requests as r with(nolock)
cross apply sys.dm_exec_sql_text(r.sql_handle) as qt
where r.session_id = t1.request_session_id) as waiter_stmt --- statement executing now
,t2.blocking_session_id as [blocker sid] --- spid of blocker
,(select text from sys.sysprocesses as p with(nolock) --- get sql for blocker
cross apply sys.dm_exec_sql_text(p.sql_handle)
where p.spid = t2.blocking_session_id) as blocker_stmt,getdate() time
from sys.dm_tran_locks as t1 with(nolock) , sys.dm_os_waiting_tasks as t2 with(nolock)
where t1.lock_owner_address = t2.resource_address

2. 查看阻塞其他进程的进程(阻塞源头):

--阻塞其他session的session 
select t2.blocking_session_id,COUNT(0) counts
from sys.dm_tran_locks as t1 with(nolock) , sys.dm_os_waiting_tasks as t2 with(nolock)
where t1.lock_owner_address = t2.resource_address
group by blocking_session_id
order by 2

3. 被阻塞时间最长的进程:

--被阻塞时间最长的session
select top 10 t1.resource_type as [lock type] ,db_name(resource_database_id) as [database]
,t1.resource_associated_entity_id as [blk object]
,t1.request_mode as [lock req] -- lock requested
,t1.request_session_id as [waiter sid] -- spid of waiter
,t2.wait_duration_ms as [wait time]
,(select text from sys.dm_exec_requests as r with(nolock) --- get sql for waiter
cross apply sys.dm_exec_sql_text(r.sql_handle)
where r.session_id = t1.request_session_id) as waiter_batch
,(select substring(qt.text,r.statement_start_offset/2,
(case when r.statement_end_offset = -1 then len(convert(nvarchar(max), qt.text)) * 2
else r.statement_end_offset end - r.statement_start_offset)/2+1)
from sys.dm_exec_requests as r with(nolock)
cross apply sys.dm_exec_sql_text(r.sql_handle) as qt
where r.session_id = t1.request_session_id) as waiter_stmt --- statement executing now
,t2.blocking_session_id as [blocker sid] --- spid of blocker
,(select text from sys.sysprocesses as p with(nolock) --- get sql for blocker
cross apply sys.dm_exec_sql_text(p.sql_handle)
where p.spid = t2.blocking_session_id) as blocker_stmt,getdate() time
from sys.dm_tran_locks as t1 with(nolock) , sys.dm_os_waiting_tasks as t2 with(nolock)
where t1.lock_owner_address = t2.resource_address
order by t2.wait_duration_ms desc

此文大致总结了通过DMV调查数据库异常的基本方法和步骤,如果大家在调查问题时能够灵活运用,相信对数据库异常情况的定位和解决能够更快更有效。

http://www.cnblogs.com/fygh/archive/2012/03/12/2391764.html

【转】数据库系统异常排查之DMV的更多相关文章

  1. 数据库系统异常排查之DMV(转)

    来源: http://www.cnblogs.com/fygh/archive/2012/03/12.html 数据库系统异常是DBA经常要面临的情景,一名有一定从业经验的DBA,都会有自己一套故障排 ...

  2. redis 异常排查

    异常排查 redis-server redis.windows.conf D:\redis-2.8.17>redis-server.exe redis.windows.conf[4692] 27 ...

  3. CPU负载过高异常排查实践与总结

    昨天下午突然收到运维邮件报警,显示数据平台服务器cpu利用率达到了98.94%,而且最近一段时间一直持续在70%以上,看起来像是硬件资源到瓶颈需要扩容了,但仔细思考就会发现咱们的业务系统并不是一个高并 ...

  4. 记一次jvm异常排查及优化

    为方便自己查看,根据工作遇到的问题,转载并整理以下jvm优化内容 有次接到客服反馈,生产系统异常,无法访问.接到通知紧急上后台跟踪,查看了数据库死锁情况--正常,接着查看tomcat 内存溢出--正常 ...

  5. Linux下Mysql启动异常排查方案

    遇到Mysql启动异常问题,可以从以下几个方面依次进行问题排查: (1)如果遇到“Can't connect to local MySQL server through socket '/tmp/my ...

  6. [C#]记录一次异常排查,关于using语法、sqlserver数据库session、DBHelper类

    最近在做一个基于asp.net和sqlserver的网站项目,发现网站运行一段时间之后,会报异常: 超时时间已到,但是尚未从池中获取连接.出现这种情况可能是因为所有池连接均在使用,并且达到了最大池大小 ...

  7. 填坑!线上Presto查询Hudi表异常排查

    1. 引入 线上用户反馈使用Presto查询Hudi表出现错误,而将Hudi表的文件单独创建parquet类型表时查询无任何问题,关键报错信息如下 40931f6e-3422-4ffd-a692-6c ...

  8. 一次django内存异常排查

    起因 Django 作为 Python著名的Web框架,相信很多人都在用,自己工作中也有项目项目在用,而在最近几天的使用中发现,部署Django程序的服务器出现了内存问题,现象就是运行一段时间之后,内 ...

  9. Linux OOM Killer造成数据库访问异常排查

    服务器上的服务器访问异常,查看/va/log/messages发现如下: Sep 22 16:08:21 safeserver kernel: java invoked oom-killer: gfp ...

随机推荐

  1. Jquery表格变色 复选框全选,反选

    /*jquery静态表格变色*/ $(".tr2").mouseover(function(){ $(this).css("background"," ...

  2. 【POJ】1284 Primitive Roots

    http://poj.org/problem?id=1284 题意:求一个素数p的原根个数.(p<=65535) #include <cstdio> #include <cst ...

  3. 硬盘分区工具gparted使用

    一.介绍 GParted是一款linux下的功能非常强大的分区工具,和windows下的‘分区魔术师’类似,操作和显示上也很相似.GParted可以方便的创建.删除分区,也可以调整分区的大小和移动分区 ...

  4. C语言中if语句

    C语言if语句后面的表达式 C语言中if关键字之后(即括号内)均为表达式. 该表达式通常是逻辑表达式或关系表达式,但也可以是其它表达式,如赋值表达式等,甚至也可以是一个变量,这些变量的值都换算成了逻辑 ...

  5. Netty_Netty系列之Netty百万级推送服务设计要点

    1. 背景 1.1. 话题来源 最近很多从事移动互联网和物联网开发的同学给我发邮件或者微博私信我,咨询推送服务相关的问题.问题五花八门,在帮助大家答疑解惑的过程中,我也对问题进行了总结,大概可以归纳为 ...

  6. Resharp最新破解方法

    ReSharper是一个JetBrains公司出品的著名的代码生成工具,其能帮助Microsoft Visual Studio成为一个更佳的IDE.它包括一系列丰富的能大大增加C#和Visual Ba ...

  7. Hibernate映射一对多双向关联关系及部门关联属性

    一对多双向关联关系:(Dept/Emp的案例) 既可以根据在查找部门时根据部门去找该部门下的所有员工,又能在检索员工时获取某个员工所属的部门. 步骤如下: 1.构建实体类(部门实体类加set员工集合) ...

  8. JAVA代码实现下载单个文件,和下载打包文件

    //下载单个文件调用方法 /**     * response     * imgPath 下载图片地址    * fileName 保存下载文件名称    * @date 2015年4月14日 下午 ...

  9. document.body.scrollTop or document.documentElement.scrollTop

      用Javascript获取DOM节点相对于页面的绝对坐标时,需要计算当前页面的滚动距离,而这个值的获取又取决于浏览器. 在Firefox或Chrome浏览器的控制台可以查看document.bod ...

  10. get_magic_quotes_gpc()

    php get_magic_quotes_gpc()函数:http://www.cnblogs.com/lsk/archive/2008/05/05/1184117.html 以及addslashes ...