使用DMV排查数据库系统异常

数据库系统异常是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调查数据库异常的基本方法和步骤,如果大家在调查问题时能够灵活运用,相信对数据库异常情况的定位和解决能够更快更有效。

时间: 2024-08-02 23:54:00

使用DMV排查数据库系统异常的相关文章

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

来源: http://www.cnblogs.com/fygh/archive/2012/03/12.html 数据库系统异常是DBA经常要面临的情景,一名有一定从业经验的DBA,都会有自己一套故障排查的方法和步骤,此文为为大家介绍一下通过系统 性能视图(SQLServer05以上版本)来排查系统异常的基本方法,希望能对大家有所帮助. 这里分两部分来介绍: 一.  从数据库连接情况来判断异常: 1. 首先我们来看一下目前数据库系统所有请求情况: --request infoselect s.se

MySQL复制异常大扫盲:快速溯源与排查错误全解

MySQL复制异常大扫盲:快速溯源与排查错误全解https://mp.weixin.qq.com/s/0Ic8BnUokyOj7m1YOrk1tA 作者介绍王松磊,现任职于UCloud,从事MySQL数据库内核研发工作,主要负责UCloud云数据库UDB的内核故障排查工作以及数据库新特性的研发工作. 复制作为MySQL原生的数据同步功能,在MySQL高可用架构中起着至关重要的作用.本文梳理了MySQL高可用产品UDB在日常运维中遇到的复制问题,并总结了当复制发生异常时,排查复制异常的方法. 一.

MTK平台如何定位显示花屏和界面错乱等绘制异常的问题?

[DESCRIPTION] 在测试手机各项功能过程中,经常会遇到概率性复现“屏幕画花了,界面画错乱了等绘制异常问题”,而且概率还非常小: 这类问题请不要直接提交eService,而是先请测试人员及工程师保留住测试现场,然后根据此条FAQ的步骤进行排查: 通常贵司提交问题的时候所提供的资料太少,无法直接定位问题,与其提交了eService之后再又去花时间复现,不如在复现问题的当下,就先按照FAQ的步骤做一个初步排查和分析. 如果在排查过程中,分析问题遇到困难,再将已经排查的结果以及排查过程中每一步

T-SQL编程中的异常处理-异常捕获(try catch)与抛出异常(throw)

原文:T-SQL编程中的异常处理-异常捕获(try catch)与抛出异常(throw) 本文出处: http://www.cnblogs.com/wy123/p/6743515.html T-SQL编程与应用程序一样,都有异常处理机制,比如异常的捕获与异常的抛出(try catch throw),本文简单介绍异常捕获与异常抛出在T-SQL编程中的实际使用 . 异常处理简单说明 异常捕获在应用程序编程中非常常见,提供了处理程序运行时出现的任何意外或异常情况的方法刚毕业的时候对于异常处理迷茫不解,

Android应用耗电问题排查

1 耗电定位工具与方法 1-1 系统提供的battery信息 1-1-1 在Android 4.4 KitKat 以前使用 adb shell dumpsys batteryinfo > d:/batterinfo.log 获取电量日志 1-1-2 在Android 4.4 KitKat 及以后使用 获取日志 adb shell dumpsys batterystats > d:/batterstats.log 获取电量日志可以使用命令清除记录后重新记录 adb shell dumpsys b

跟我学-域名解析故障排查技巧

天苍苍,野茫茫,网站一瘫,唯有泪两行!!客户跳,老板叫,解析故障,心惊又肉跳!! 对企业网站来说,很怕出现网站打不开的情况,一旦发生,准会发现公司技术部呈现一片哀嚎景象.为了让运维的难兄难弟们做个精致的小白领,小编特别为你们总结了一套<域名解析故障排查技巧实操全网最全手册>,并分为“初阶版”“进阶版”,跟我学完保您在排查解析故障方面,脑回路神清晰,分分钟就能定位问题.为了助您减少客户不可用时间,并赢得老板信任,今天就来听听小编跟大家唠唠域名解析那点事儿. 因为DNS是互联网流量的入口,所以企业

SQL 笔记 By 华仔

-------------------------------------读书笔记------------------------------- 笔记1-徐 最常用的几种备份方法 笔记2-徐 收缩数据库的大小的方法 笔记3-徐 设置数据库自动增长注意要点 笔记4-徐 模仿灾难发生时还原adventurework数据库 示例 stopat 笔记5-徐 检查日志文件不能被截断的原因 笔记6-徐 检测孤立用户并恢复孤立用户到新的服务器 解决数据库镜像孤立用户问题 笔记7-徐 SQLSERVER日志记录

mysql的&quot;双1设置&quot;-数据安全的关键参数(案例分享)

mysql的"双1验证"指的是innodb_flush_log_at_trx_commit和sync_binlog两个参数设置,这两个是是控制MySQL 磁盘写入策略以及数据安全性的关键参数.下面从参数含义,性能,安全角度阐述两个参数为不同的值时对db 性能,数据的影响. 一.参数意义 innodb_flush_log_at_trx_commit如果innodb_flush_log_at_trx_commit设置为0:log buffer将每秒一次地写入log file中,并且log

Xcode 调试技巧-b

随着Xcode 5的发布,LLDB调试器已经取代了GDB,成为了Xcode工程中默认的调试器.它与LLVM编译器一起,带给我们更丰富的流程控制和数据检测的调试功能.LLDB为Xcode提供了底层调试环境,其中包括内嵌在Xcode IDE中的位于调试区域的控制面板,在这里我们可以直接调用LLDB命令 1.必备篇 1.1 打印变量:print/po print:打印变量的值可以使用print命令,该命令如果打印的是简单类型,则会列出简单类型的类型和值.如果是对象,还会打印出对象指针地址: print