现像是这样的,数据库运行几天或不定时,CPU内存将突然大幅增长,CPU在80%~100%之间跳动,内存涨到16G上下(正常情况是6G左右),打开活动监视器,发现有几百个状态为"己挂起"的进程。所有的应用都己无法连接数据库了。
上次出现这样的情况,重启数据库服务后,没多久马上又是以上的现像。后来重启数据库服务器后暂时解决。
没想到,过了三天,以上的情况又出现了。因为没有DBA,平时数据库都是自己公司人维护,请高人指点一下,怎样查以上的问题?
上次出现这样的情况,重启数据库服务后,没多久马上又是以上的现像。后来重启数据库服务器后暂时解决。
没想到,过了三天,以上的情况又出现了。因为没有DBA,平时数据库都是自己公司人维护,请高人指点一下,怎样查以上的问题?
select spid, blocked, loginame, last_batch, status, cmd, hostname, program_name
from sysprocesses
where spid in
( select blocked from sysprocesses where blocked <> 0 ) or (blocked <>0)
/*--处理死锁 查看当前进程,或死锁进程,并能自动杀掉死进程 因为是针对死的,所以如果有死锁进程,只能查看死锁进程
当然,你可以通过参数控制,不管有没有死锁,都只查看死锁进程--邹建 2004.4--*//*--调用示例 exec p_lockinfo
--*/
create proc p_lockinfo
@kill_lock_spid bit=1, --是否杀掉死锁的进程,1 杀掉, 0 仅显示
@show_spid_if_nolock bit=1 --如果没有死锁的进程,是否显示正常进程信息,1 显示,0 不显示
as
declare @count int,@s nvarchar(1000),@i int
select id=identity(int,1,1),标志,
进程ID=spid,线程ID=kpid,块进程ID=blocked,数据库ID=dbid,
数据库名=db_name(dbid),用户ID=uid,用户名=loginame,累计CPU时间=cpu,
登陆时间=login_time,打开事务数=open_tran, 进程状态=status,
工作站名=hostname,应用程序名=program_name,工作站进程ID=hostprocess,
域名=nt_domain,网卡地址=net_address
into #t from(
select 标志='死锁的进程',
spid,kpid,a.blocked,dbid,uid,loginame,cpu,login_time,open_tran,
status,hostname,program_name,hostprocess,nt_domain,net_address,
s1=a.spid,s2=0
from master..sysprocesses a join (
select blocked from master..sysprocesses group by blocked
)b on a.spid=b.blocked where a.blocked=0
union all
select '|_牺牲品_>',
spid,kpid,blocked,dbid,uid,loginame,cpu,login_time,open_tran,
status,hostname,program_name,hostprocess,nt_domain,net_address,
s1=blocked,s2=1
from master..sysprocesses a where blocked<>0
)a order by s1,s2select @count=@@rowcount,@i=1if @count=0 and @show_spid_if_nolock=1
begin
insert #t
select 标志='正常的进程',
spid,kpid,blocked,dbid,db_name(dbid),uid,loginame,cpu,login_time,
open_tran,status,hostname,program_name,hostprocess,nt_domain,net_address
from master..sysprocesses
set @count=@@rowcount
endif @count>0
begin
create table #t1(id int identity(1,1),a nvarchar(30),b Int,EventInfo nvarchar(255))
if @kill_lock_spid=1
begin
declare @spid varchar(10),@标志 varchar(10)
while @i<=@count
begin
select @spid=进程ID,@标志=标志 from #t where id=@i
insert #t1 exec('dbcc inputbuffer('+@spid+')')
if @标志='死锁的进程' exec('kill '+@spid)
set @i=@i+1
end
end
else
while @i<=@count
begin
select @s='dbcc inputbuffer('+cast(进程ID as varchar)+')' from #t where id=@i
insert #t1 exec(@s)
set @i=@i+1
end
select a.*,进程的SQL语句=b.EventInfo
from #t a join #t1 b on a.id=b.id
end
go
对于问题,每个的切入点和故障排除的方式方法不同。4、对于故障的部分,我会先界定硬件的部分,再界定软件的部分,根据现实的环境从比较容易点开始入手排除。对此,建议:
1) SQL的部分:观察是否在固定时间发生异常,比如在每月或者每天某个时段,因为你绝对没有做基准,所以无法直接通过数据去分析。
该时段是否存在大量的统计查询,比如有客户端去做大量的同比和环比数据调用。
2) 如果情况大致相近,在异常出现时,检查进程和连接信息。这里不推荐用Profiler去做分析,原因暂不说明。3) 查询语句参考以下链接:http://topic.csdn.net/u/20110929/14/26c2f7e0-6484-4c30-bc3a-1edc80498ccc.html4) 用语句方式二进行异常时段查询,然后分析连接端提交的SQL语句,根据你的实际情况去分析哪个用户提交SQL的是上述情况。注)这些都是基本的应用,心态一定要放端、冷静。 其次,从这次开始,如果你想做好一份兼职DBA,那么开始关注Profiler、PAL、SQLdiag等,以上部分希望对你是有用的。
如果不是,先从硬件开始监测。
硬件没有问题的话,检测数据库,
1、检查系统日志,sql日志。
2、这个时候打开windows性能监视器,sql profiler,活动监视器,查看是不是T-sql语句执行过程中的问题。以上没有问题。
3、查看死锁,如果有,则找出死锁形成的原因,优化查询。