Oracle数据库无响应故障处理方式

Oracle数据库无响应故障处理方式,第1张

Oracle数据库无响应故障处理方式

Oracle数据库无响应故障,简单地讲就是数据库实例不能响应客户端发起的请求,客户端提交一个SQL后,就一直处于等待数据库实例返回结果的状态。更严重的现象是客户端根本不能连接到数据库,发起一个连接请求后,一直处于等待状态。Oracle数据库无响应故障怎么处理呢下面跟我一起来学习Oracle数据库无响应故障的处理方法吧!

无响应的故障现象一般有以下几种:

1Oracle的进程在等待某个资源或事件

这种现象一般可以从V$SESSION_WAT、V$LATCH、V$LATCHHOLDER等动态视图中检查进程正在等待的资源或事件,而被等待的资源或事件,一直都不能被获取,甚至是很长时间都不可获得。如果这个正在等待的进程持有了其他的资源,则会引起其他的进程等待,这样就很可能引起实例中大范围的会话发生等待。由于进程在等待资源或事件时,通常都处于SLEEP状态,消耗的CPU资源非常少(在等待latch时要稍微多消耗一些CPU资源),所以从OS来看,CPU的消耗并不高,甚至是非常低。

这种因为等待而引起的个别进程Hang,相对比较容易处理。

2 OracleProcess Spins

所谓Spin,就是指Oracle进程中的代码在执行某个过程时,陷入了循环。在V$SESSION视图中,往往可以看到Hang住的会话,一直处于“ACTIVE”状态。对于这样的会话,用“alter system kill session ‘sid,serial#’”命令也不能完全断开会话,会话只能被标记为“killed”,会话会继续消耗大量的CPU。进程Spins由于是在做循环,CPU的消耗非常大,从OS上明显可以看到这样的进程,通常会消耗整个CPU的资源。

而对于这样的Hang住的会话,处理起来相对比较复杂,并且为了从根本上解决问题,需要超过DBA日常维护所需要的技能。

从故障范围来看,无响应故障可以分为以下几种情况:

1 单个或部分会话(进程)Hang住

这种情况属于小范围的故障,业务影响相对较小,一般来说只会影响业务系统的个别模块。在一个多应用系统的数据库上面,如果Hang住的会话比较多,则影响的可能是其中的一个应用系统。这里有一个例外,如果Hang住的进程是系统后台进程,如pmon、smon等,则影响的范围就非常大了,最终甚至会影响整个数据库及所有应用系统。还有值得注意的是,即使是少部分会话Hang住,也要及时处理,否则极有可能会扩散到整个系统。

2 单个数据库实例Hang住

这种情况造成的影响非常大。在这个实例上的所有应用系统均受到严重影响,并且在找到根源并最终解决问题之前,数据库实例往往须要重启。

3 OPS或RAC中的多个实例或所有实例都Hang住

在这种情况下,即使是OPS或RAC,都已经没办法提供高可用特性了。使用这个数据库的所有应用系统将不能继续提供服务,这种情况往往须要重启。

无响应故障成因分析

Oracle数据库无响应,一般主要由以下几种原因引起:

1 数据库主机负载过高,严重超过主机承受能力

比如应用设计不当,数据库性能低下,活动会话数的大量增加,导致数据库主机的负载迅速增加,数据库不能正常 *** 作,并最终Hang住;主机物理内存严重不足,引起大量的换页,特别是在SGA中的内存被大量换出到虚拟内存时,数据库实例往往就会Hang住。

2 日常维护不当、不正确的 *** 作引起数据库Hang住

比如归档日志的存储空间满,导致数据库不能归档,引起数据库Hang住;在一个大并发的繁忙的系

统上,对DML *** 作比较多的大表进行move、增加外键约束等 *** 作也可能使系统在短时间内负载大幅升高,并引起数据库系统Hang住;不正确的资源计划(Resource Plan)配置,使进程得不到足够的CPU等。

3 Oracle数据库的Bug

几乎每个版本都存在着会导致数据库系统Hang住的Bug,这些Bug会在一些特定的条件下触发,特别是在RAC数据库中,引起数据库Hang住的Bug比较多。

4 其他方面的一些原因

比如在RAC数据库中,如果一个节点退出或加入到RAC的过程中,当进行Resource Reconfiguration时,会使系统冻结一段时间,也有可能使系统Hang住。

以上所描述的几种常见的会导致Oracle数据库实例Hang住的原因中,大部分的情况是可以避免的,只要维护得当,一般不会出现这种故障。对于Oracle数据库Bug所导致的数据库无响应故障,由于是在特定的情况下才会触发,所以如果能够尽量对数据库打上最新版本的补丁,并且熟悉当前版本中会导致系统Hang住的Bug以及触发条件,就能够最大限度地避免这种故障的发生,提高系统的可用性。

那么,在数据库Hang住的情况下,如何去分析并发现导致问题的根源一方面,由于系统Hang住会导致业务系统不可用,为了能够尽快地恢复业务,须快速地判断问题所在,然后Kill掉引起故障的会话和进程,或者数据库实例不得不重启以迅速恢复业务;但另一方面,如果只是重启数据库或Kill会话和进程来解决问题,在很多情况下是治标不治本的办法,在以后故障随时可能会出现。如何在二者之间进行抉择呢对于数据库Hang故障的处理,首先是尽可能地收集到系统Hang住时的状态数据,然后尽快地恢复业务,恢复业务后分析收集到的数据,找到数据库系统Hang住的真正原因,然后再进行相应的处理。下一节将详细描述数据库系统Hang住后的处理流程。

无响应故障处理流程

对于Oracle无响应故障的处理,我们可以按下图所示的流程进行。

值得注意的是,上图并不是一个完整的Oracle数据库故障处理流程图,只是处理Oralce数据库无响应这一类特定的故障的流程,只列出了针对这一特定类型故障处理时的关键处理点。不过既然是故障,所以这类故障的处理流程与其他故障的处理流程,有着非常相似的地方。

下面是整个流程的详细说明:

1 在出现数据库无响应故障后,首先确认系统的影响范围,如上节所描述的',是部分业务系统或模块还是所有的业务系统都受影响,是不是整个实例或多个实例都无响应。同时应询问系统维护和开发人员,受影响的系统在出现故障前是否有过变动,包括主机硬件、 *** 作系统、网络、数据库以及应用等。有时一个细小的变动就可能导致出现数据库Hang住这样严重的故障。曾经遇到一个库,应用只是修改了一个SELECT语句就导致了数据库Hang住。

2 为了避免由于网络、数据库监听或客户端因素影响分析,建议都登录到主机上进行 *** 作。

3 如果主机不能登录(为了避免干扰流程主线,这里不讨论如网络问题这样也会导致不能连接的故障),尝试关闭出现问题的业务系统,甚至是所有的业务系统。如果关闭了所有的业务系统之后,仍然不能连接,则只有考虑重新启动数据库主机。在数据库主机重新启动后,使用 *** 作系统工具或OSW等长期监控 *** 作系统的资源使用,同时监控Oracle数据库的性能和等待等。

4 登录上主机后,先用top、topas等命令简单观察一下系统。看看系统的CPU使用、物理内存和虚拟内存的使用、IO使用等情况。

5 使用SQLPLUS连接数据库,如果不能连接,则只能从 *** 作系统上观察系统中是否有异常的现象,比如占用CPU过高的进程。使用gdb、dbx等debugger工具对数据库进行system state dump;使用strace、truss等工具检查异常进程的系统调用;使用pstack、procstack等工具察看异常进程的call stack等。

6 使用SQLPLUS连接上数据库后,进行hanganalyze、system state dump等 *** 作;或检查等待事件、异常会话等正在执行的SQL等待。

7 找到故障产生的原因,如果暂时找不到原因,尽量收集数据。

8确良如果应用急须恢复,可通过Kill会话、重启数据库实例等方式,先恢复应用。

9 根据最终诊断结果,对数据库升级打补丁,或者修改应用等方式从根本上解决问题。

怎样避免数据库出现无响应故障

作为Oracle数据库DBA,除了处理故障之外,更重要的是如何预防故障的发生。根据前面对数据库无响应故障的成因分析,在日常的维护工作中,须做到以下几点:

1 进行正确的维护 *** 作

很多的数据库无响应故障都是由于不正确的维护 *** 作引起的。应避免在业务高峰期做大的维护 *** 作,比如像move、加主外键约束等会长时间锁表的 *** 作。如果的确需要,尽量使用正确的 *** 作方法。比如用ONLINE方式重建索引;建主键、唯一键约束时先建索引,然后在建约束时指定新建的索引,等等。也就是保证系统的并发性、可伸缩性,避免系统串行 *** 作的出现。

2 优化应用设计,优化数据库性能

为避免性能问题导致在业务高峰期数据库不能及时有效处理来自业务的请求,甚至于完全Hang住。对于数据库中存在串行访问的部分进行优化,比如latch、enqueue,还包括不合理的sequence设计等。特别是在RAC数据库中,严重串行访问等待往往更容易引起严重的性能问题。优化应用设计,使数据库具有更好的可伸缩性和并行处理能力,能够有效地避免性能问题引起的数据库Hang住。

3 利用监控系统随时监控系统负载

遇到系统负载过高,内存不足,OS中虚拟内存换页很频繁等情况时,及时采取措施;监控Oracle数据库的核心进程,如pmon、smon等,看是否有异常,如过高的CPU消耗。出现异常应立即处理;监控归档空间和日志切换;监控数据库中的等待事件,比如是否有大量的enqueue、log file switch (archiving needed)、resmgr:become active等待事件等。

4 为数据库打上补丁

很多的无响应故障是由于Oracle的Bug引起的,数据库DBA应关注当前版本中有哪些Bug会导致数据库Hang住,尽量为数据库打上解决这些Bug的补丁。

;

首先,我们在主数据库中创建“KILL2”这个进程,代码如下所示(参考图一):

USE [master]

GO

IF EXISTS (SELECT FROM masterdbosysobjects

WHERE id = OBJECT_ID(N'[kill2]') AND type in (N'P', N'PC'))

DROP PROCEDURE [dbo][kill2]

GO

--Usage1: Kill2 '51-57' --> Kills all the session IDs from 51 to 57

--Usage2: Kill2 '58' --> Kills the session IDs 58

--Usage3: Kill2 '51,56,100,58'

--> Kills the session IDs 51,56,100 and 58

--Usage4: Kill2 'DB=MyDatabase'

--> Kills all the session IDs that are connected

to the database "MyDatabase"

use master

go

set concat_null_yields_null off

go

create procedure kill2 @param2 varchar(500)

as

--declare @param2 varchar(500)

declare @param varchar(500)

declare @startcount int

declare @killcmd varchar(100)

declare @endcount int

declare @spid int

declare @spid2 int

declare @tempvar varchar(100)

declare @tempvar2 varchar(100)

--set @param2 ='54'

set @param=REPLACE(@param2,' ','')

if CHARINDEX('-',@param) <> 0

begin

select @startcount= convert(int,SUBSTRING(@param,1,charindex('-',@param)-1))

select @endcount=convert(int,SUBSTRING(@param,charindex('-',@param)+1,(LEN(@param)-charindex('-',@param))))

print 'Killing all SPIDs from ' + convert(varchar(100),@startcount)+' to ' +convert(varchar(100),@endcount)

while @startcount <=@endcount

begin

set @spid=(select spid from masterdbosysprocesses where spid=@startcount and spid>50)

if @spid = @startcount

begin

print 'Killing '+convert(varchar(100),@startcount)

set @killcmd ='Kill '+convert(varchar(100),@startcount)

exec(@killcmd)

end

else

begin

Print 'Cannot kill the SPID ' +convert(varchar(100),@startcount) + ' because it does not Exist'

end

set @startcount=@startcount + 1

end

end

if CHARINDEX(',',@param) <> 0

begin

set @tempvar =@param

while charindex(',',@tempvar ) <> 0

begin

SET @tempvar2=left(@tempvar,charindex(',',@tempvar)-1)

set @spid=(select spid from masterdbosysprocesses where spid=CONVERT(varchar(100),@tempvar2) and spid>50)

if @spid = CONVERT(varchar(100),@tempvar2)

begin

print 'Killing '+CONVERT(varchar(100),@tempvar2)

set @killcmd='Kill '+CONVERT(varchar(100),@tempvar2)

exec (@killcmd)

end

else

begin

Print 'Cannot kill the SPID ' +CONVERT(varchar(100),@tempvar2) + ' because it does not Exist'

end

set @tempvar =REPLACE(@tempvar,left(@tempvar,charindex(',',@tempvar)),'')

end

set @spid=(select spid from masterdbosysprocesses where spid=CONVERT(varchar(100),@tempvar) and spid>50)

if @spid = CONVERT(varchar(100),@tempvar)

begin

print 'Killing '+CONVERT(varchar(100),@tempvar)

set @killcmd='Kill '+CONVERT(varchar(100),@tempvar)

exec (@killcmd)

end

else

begin

Print 'Cannot kill the SPID ' +CONVERT(varchar(100),@tempvar) + ' because it does not Exist'

end

end

if CHARINDEX('=',@param2) <>0

begin

print 'Killing all the SPIDs that are connected to the database '+RIGHT(@param2,(len(@param2)-3))

declare dbcursor

cursor forward_only for select SPID from masterdbosysprocesses where DB_NAME(dbid) = RIGHT(@param2,(len(@param2)-3))

open dbcursor

fetch dbcursor into @spid

while @@FETCH_STATUS =0

begin

set @spid2=(select spid from masterdbosysprocesses where spid=@spid and spid>50)

if @spid = @spid2 begin

print 'Killing '+CONVERT(varchar(100),@spid2)

set @killcmd='Kill '+CONVERT(varchar(100),@spid2)

exec (@killcmd)

end

else

begin

Print 'Cannot kill the SPID ' +CONVERT(varchar(100),@spid2) + ' because it does not Exist'

end

fetch dbcursor into @spid

end

close dbcursor

deallocate dbcursor

end

if CHARINDEX('-',@param)=0 and CHARINDEX(',',@param) = 0 and CHARINDEX('=',@param)=0

begin

set @spid=(select spid from masterdbosysprocesses where spid=CONVERT(varchar(100),@param) and spid>50)

if @spid = CONVERT(varchar(100),@param)

begin

print 'Killing '+CONVERT(varchar(100),@param)

set @killcmd='Kill '+CONVERT(varchar(100),@param)

exec (@killcmd)

end

else

begin

Print 'Cannot kill the SPID ' +CONVERT(varchar(100),@param) + ' because it does not Exist'

end

end

go

--kill2 '51'

--go

--kill2 '51-56'

--go

--kill2 '56,57,58,52'

--go

--kill2 'db=AdventureWorks2008'

--kill2 'db=My Database'

--go

--sp_who

  图一

现在,我们假设进程ID(SPID)为51、52、53、54、55、57这几个进程(见图二)连接到了SQL Server数据库,而我们只想把进程ID为54、55和57的进程结束掉。

图二

执行以下命令。注意,在这个例子当中还在命令中加入了其他几个SQL Server中不存在的SPID:61和100。 

use master

go

kill2 '54,57,55,61,100'

go

运行结果: 

Killing 54

Killing 57

Msg 6104, Level 16, State 1, Line 1

Cannot use KILL to kill your own process

Cannot kill the SPID 55 because it does not Exist

Cannot kill the SPID 61 because it does not Exist

Cannot kill the SPID 100 because it does not Exist

图三

我们可以从结果(见图三)看到,执行指令后成功终止了SPID 54。当试图终止57时失败了。同时结果也显示了为什么没能终止特定SPID的信息

下面,假设我们有51、52、53、54、55、57、58、59和60这几个SPID,而我们的目标是结束SPID从25到70的进程。

执行以下命令:

use master

go

kill2 '25-75'

go

运行结果: 

Killing all SPIDs from 25 to 75

Cannot kill the SPID 25 because it does not Exist

Cannot kill the SPID 48 because it does not Exist

Cannot kill the SPID 49 because it does not Exist

Cannot kill the SPID 50 because it does not Exist

Killing 51

Killing 52

Killing 53

Killing 54

Killing 55

Cannot kill the SPID 56 because it does not Exist

Killing 57

Msg 6104, Level 16, State 1, Line 1

Cannot use KILL to kill your own process

Killing 58

Killing 59

Killing 60

Cannot kill the SPID 61 because it does not Exist

Cannot kill the SPID 75 because it does not Exist

图四

从结果(见图四)我们可以看到“KILL2”存储过程忽略了所有SPID小于50的连接,而结束了从51到70的所有进程。

接下来,假设我们要终结掉所有连接到数据库AdventureWorks2008的会话,同时又假设SPID为53、54、58和60的进程连接到了该数据库(见图五)。

图五

现在,我们执行以下的T-SQL语句结束掉所有这些会话。 

Use master

go

kill2 'db=AdventureWorks2008'

go

运行结果:

Killing all the SPIDs that are connected to the database AdventureWorks2008

Killing 53

Killing 54

Killing 58

Killing 60

图六

从结果(见图六)我们可以看到“KILL2”存储过程终止了所有连接到AdventureWorks2008数据库的会话。

用法四

“KILL2”存储过程的第四种用法类似于“KILL命令,也就是一次解决一个会话,如下所示: 

Use master

go

kill2 '56'

go

 

数据库中死锁是什么产生的

Mysql数据库里的 锁,根据存储引擎不同,一般有行锁 表锁。

其实锁的作用跟文件锁 是差不多的就是避免同时对某表 或某条记录进行修改。

死锁 我估计是2个应用同时锁住了 同一个表 或 同一条记录。这样谁也释放不了资源。

个人愚见。欢迎拍砖。

使用MySQL数据库,都有哪些情况易出现死锁的情况?

在老版本的MySQL 322中,MySQL的单表限大小为4GB,当时的MySQL的存储引擎还是ISAM存储引擎。但是,当出现MyISAM存储引擎之后,也就是从MySQL 323开始,MySQL单表最大限制就已经扩大到了64PB了(官方文档显示)。也就是说,从目前的技术环境来看,MySQL数据库的MyISAM存储 引擎单表大小限制已经不是有MySQL数据库本身来决定,而是由所在主机的OS上面的文件系统来决定了。

而MySQL另外一个最流行的存储引擎之一Innodb存储数据的策略是分为两种的,一种是共享表空间存储方式,还有一种是独享表空间存储方式。

当使用共享表空间存储方式的时候,Innodb的所有数据保存在一个单独的表空间里面,而这个表空间可以由很多个文件组成,一个表可以跨多个文件存在,所 以其大小限制不再是文件大小的限制,而是其自身的限制。从Innodb的官方文档中可以看到,其表空间的最大限制为64TB,也就是说,Innodb的单 表限制基本上也在64TB左右了,当然这个大小是包括这个表的所有索引等其他相关数据。

而当使用独享表空间来存放Innodb的表的时候,每个表的数据以一个单独的文件来存放,这个时候的单表限制,又变成文件系统的大小限制了。

oracle经常死锁,锁定数据库的一些表,导致oracle死锁的原因一般有那些?

一般情况只发生锁超时,就是一个进程需要访问数据库表或者字段的时候,另外一个程序正在执行带锁的访问(比如修改数据),那么这个进程就会等待,当等了很久锁还没有解除的话就会锁超时,报告一个系统错误,拒绝执行相应的SQL *** 作。发生死锁的情况比较少,比如一个进程需要访问两个资源(数据库表或者字段),当获取一个资源的时候进程就对它执行锁定,然后等待下一个资源空闲,这时候如果另外一个进程也需要两个资源,而已经获得并锁定了第二个资源,那么就会死锁,因为当前进程锁定第一个资源等待第二个资源,而另外一个进程锁定了第二个资源等待第一个资源,两个进程都永远得不到满足。

erp100

如何解决多线程造成的数据库死锁

多线程是很容易造成死锁,一般情况下死锁都是因为并发 *** 作引起的。我不懂JAVA,但死锁这个问题每种开发工具和数据库都会碰到解决办法是:

1、程序方面优化算法(如有序资源分配法、银行算法等),在一个程序里,能不用多线程更新同一张数据库表 尽量不要用,如果要用,其避免死锁的算法就很复杂。

2、数据库方面设置等待超时时间

3、发生死锁后直接KILL掉数据库进程

查询数据库的时候,在什么情况下可能会导致死锁

察看死锁

select sesssid,

sessserial#,

looracle_username,

loos_user_name,

aoobject_name,

lolocked_mode

from v$locked_object lo,

dba_objects ao,

v$session sess

where aoobject_id = loobject_id and losession_id = sesssid

order by aoobject_name ;

清除死锁

alter system kill session sid,serial#

怎么查看数据库死锁,和解决方法

exec sp_lock 快捷键 C_2

exec sp_who active exec sp_who快捷键 C_1

用Profiler里面的Locks->Deadlock graph 监控看看,如果看到了死锁图,就可以比较形象地展现死锁发生的过程,还可以看到锁的具体类型和过程里面的语句,对你诊断会有帮助。

Declare @LockTab table( spid int,dbid int ,ObjId int,IndId int ,Type varchar(50),Resource varchar(50),Mode varchar(50),Status varchar(50))

insert into @LockTab exec sp_lock

Declare @ActiveTab table(spid int,ecid int,status varchar(50),loginname varchar(50),hostname varchar(50),blk int,dbname varchar(50),cmd varchar(50),request_id int)

insert into @ActiveTab exec sp_who active

select from @LockTab lt

left join @ActiveTab at on ltspid=atspid

数据库发生死锁会出现什么情况

数据只能查询,删和盯都不超时在数据库中==>管理==>活动监视器中查找到相关锁,然后终止掉就OK

数据库查询时可能造成死锁吗

查询不会产生死锁。

更新有可能会造成死锁。死锁不需要干预的,系统会定时清理死锁并在alert里记录。估计你感兴趣的应该是其他的锁比如行锁、表锁或者是锁等待之类的。

数据库,因为高访问量,造成线程死锁的原因是,如何来解除呢?

死锁主要是资源共享造成的冲突。比如a拥有资源1,需要资源2才能运行。

b拥有资源2,需要资源1才能。这是就产生资源1、2都有,叮a,b都无法运行的情况。解决死锁的方法有很多,你要了解更多的信息就去看看 *** 作系统的数。里面讲的很详细。

数据库中解决死锁的方法:

1限制同时访问数据库的用户数。

2超时线程自动释放。

3优化访问方式

多个程序访问一个数据库出现死锁,怎么处理

如果是sql数据库本身就不会锁死表,锁死是你的逻辑控制的,一般不通过锁死来 *** 作数据库。看你怎么用,或者可以提出你的具体问题。

1、在做Oracle监听程序测试时,发现帐户已经被锁定。

2、在数据库安装电脑上,点击开始打开运行窗口。

3、在运行窗口输入CMD,调出命令提示符界面。

3、在命令提示符下面,用管理员身份登入到数据库sqlplus / as sysdba。

4、输入解锁命令alter user Scott account unlock后回车。

5、看见用户已更改的字样,表示命令已成功执行。

6、再切换到监听程序验证,原来的ora-28000帐户被锁定的提示已经不存在了。用户解锁成功。

RESTORE前自己不能连接到需要RESTORE的数据库,一般都是连接到master数据库,其他的进程也不允许连接到这个RESTORE的数据库;在kill的时候肯定是不能kill自己的进程,自己的进程要kill的话不如退出(退出了后进程自然没有了),所以kill的时候要判断一下自己的进程号。

可以用sp_who'active'看一下午blk字段是否为0,如是其它数x,说明这个数可能就是锁,再用sp_who数x看一下它下面的blk是否有数,这样查下去,如果它下面没有数并且是查询状态或是等待状态等(除更新及插入状态)都可以用kill数x

以上就是关于Oracle数据库无响应故障处理方式全部的内容,包括:Oracle数据库无响应故障处理方式、如何终止SQL Server中的用户进程、数据库死锁产生的原因等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/sjk/9465266.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-28
下一篇 2023-04-28

发表评论

登录后才能评论

评论列表(0条)

保存