您的位置:首页 > 数据库 > Oracle

ORACLE快速彻底Kill掉的会话(转载)

2015-02-26 10:33 393 查看
[code]SQL>connetl/etl

Connected.

SQL>updatetestsetstatus='invalid';


55944rowsupdated.


SQL>updatetest2setdropped='Y';


3090rowsupdated.

[/code]
[/code]
会话2:


[code]
[code]

SQL>showuser

USERis"SYS"

SQL>updateetl.test2setdropped='Y';


3090rowsupdated.

[/code]
[/code]
会话3


[code]
[code]

SQL>selectsaddr,sid,serial#,paddr,username,statusfromv$sessionwhereusername=upper('etl')orusername=upper('sys');


SADDRSIDSERIAL#PADDRUSERNAMESTATUS

------------------------------------------------------------------------------------------

000000025C233B002733353000000025F1D1FC8ETLINACTIVE

000000025C23A6083711448000000025F1D27B0SYSACTIVE

000000025C24BC506354311000000025F1D5F08SYSACTIVE



SQL>altersystemkillsession'27,33353';


Systemaltered.


SQL>selectsaddr,sid,serial#,paddr,username,statusfromv$sessionwhereusername=upper('etl')orusername=upper('sys');


SADDRSIDSERIAL#PADDRUSERNAMESTATUS

------------------------------------------------------------------------------------------

000000025C233B002733353000000025C21A0B0ETLKILLED

000000025C23A6083711448000000025F1D27B0SYSACTIVE

000000025C24BC506354311000000025F1D5F08SYSINACTIVE

[/code]
[/code]




如下所示,我杀掉了其中两个会话后,这两个会话的地址都变为000000025C21A0B0了(请见PADDR列)。当在Oracle中killsession以后,Oracle只是简单的把相关session的paddr指向同一个虚拟地址.此时v$process和v$session失去关联,进程就此中断。然后Oracle就等待PMON去清除这些Session.所以通常等待一个被标记为Killed的Session退出需要花费很长的时间.如果此时被Kill的process,重新尝试执行任务,那么马上会收到进程中断的提示,process退出,此时Oracle会立即启动PMON来清除该session.这被作为一次异常中断处理.






[code]
[code]SQL>altersystemkillsession'63,54311';


Systemaltered.


SQL>selectsaddr,sid,serial#,paddr,username,status

fromv$sessionwhereusername=upper('etl')orusername=upper('sys');


SADDRSIDSERIAL#PADDRUSERNAMESTATUS

------------------------------------------------------------------------------------------

000000025C233B002733353000000025C21A0B0ETLKILLED

000000025C23A6083711448000000025F1D27B0SYSACTIVE

000000025C24BC506354311000000025C21A0B0SYSKILLED

[/code]
[/code]
我们根据下面SQL找到进程的地址,然后在v$process里面找到对应的spid,然后从操作系统中杀掉该进程。


[code]
[code]SQL>selectp.addrfromv$processpwherepid<>1

2minus

3selects.paddrfromv$sessions;


ADDR

----------------

000000025F1D1FC8

000000025F1D5F08




SQL>selectsaddr,sid,serial#,paddr,username,statusfromv$session

whereusername=upper('etl')orusername=upper('sys');


SADDRSIDSERIAL#PADDRUSERNAMESTATUS

------------------------------------------------------------------------------------------

000000025C233B002733353000000025C21A0B0ETLKILLED

000000025C23A6083711448000000025F1D27B0SYSACTIVE

000000025C24BC506354311000000025C21A0B0SYSKILLED


SQL>selectaddr,pid,spid,usernamefromv$processwhereaddrin('000000025F1D1FC8','000000025F1D5F08');


ADDRPIDSPIDUSERNAME

-----------------------------------------------------

000000025F1D1FC82212959oracle

000000025F1D5F083812971oracle


SQL>!kill-912959


SQL>!kill-912971


SQL>selectsaddr,sid,serial#,paddr,username,status

fromv$sessionwhereusername=upper('etl')orusername=upper('sys');


SADDRSIDSERIAL#PADDRUSERNAMESTATUS

------------------------------------------------------------------------------------------

000000025C23A6083711448000000025F1D27B0SYSACTIVE

[/code]
[/code]

在ORACLE数据库杀掉会话进程有三种方式:

1:ALTERSYSTEMKILLSESSION

关于KILLSESSIONClause,如下官方文档描述所示,altersystemkillsession实际上不是真正的杀死会话,它只是将会话标记为终止。等待PMON进程来清除会话。


[code]
[code]TheKILLSESSIONclauseletsyoumarkasessionasterminated,rollbackongoingtransactions,releaseallsessionlocks,andpartiallyrecoversessionresources.Tousethisclause,yourinstancemusthavethedatabaseopen.Yoursessionandthesessiontobeterminatedmustbeonthesameinstanceunlessyouspecifyinteger3.YoumustidentifythesessionwiththefollowingvaluesfromtheV$SESSIONview:


Forinteger1,specifythevalueoftheSIDcolumn.


Forinteger2,specifythevalueoftheSERIAL#column.


Fortheoptionalinteger3,specifytheIDoftheinstancewherethetargetsessiontobekilledexists.YoucanfindtheinstanceIDbyqueryingtheGV$tables.

Ifthesessionisperformingsomeactivitythatmustbecompleted,suchaswaitingforareplyfromaremotedatabaseorrollingbackatransaction,thenOracleDatabasewaitsforthisactivitytocomplete,marksthesessionasterminated,andthenreturnscontroltoyou.Ifthewaitinglastsaminute,thenOracleDatabasemarksthesessiontobeterminatedandreturnscontroltoyouwithamessagethatthesessionismarkedtobeterminated.ThePMONbackgroundprocessthenmarksthesessionasterminatedwhentheactivityiscomplete.

Whetherornotthesessionhasanongoingtransaction,OracleDatabasedoesnotrecovertheentiresessionstateuntilthesessionuserissuesarequesttothesessionandreceivesamessagethatthesessionhasbeenterminated.

[/code]
[/code]
可以使用ALTERSYSTEMKILLSESSION'sid,serial#'IMMEDIATE来快速回滚事物、释放会话的相关锁、立即返回当前会话的控制权。

SpecifyIMMEDIATEtoinstructOracleDatabasetorollbackongoingtransactions,releaseallsessionlocks,recovertheentiresessionstate,andreturncontroltoyouimmediately.

2:ALTERSYSTEMDISCONNECTSESSION

ALTERSYSTEMDISCONNECTSESSION杀掉专用服务器(DEDICATEDSERVER)或共享服务器的连接会话,它等价于从操作系统杀掉进程。它有两个选项POST_TRANSACTION和IMMEDIATE,其中POST_TRANSACTION表示等待事务完成后断开会话,IMMEDIATE表示中断会话,立即回滚事务。

SQL>ALTERSYSTEMDISCONNECTSESSION'sid,serial#'POST_TRANSACTION;

SQL>ALTERSYSTEMDISCONNECTSESSION'sid,serial#'IMMEDIATE;

3:KILL-9SPID(Linux)或orakillORACLE_SIDspid (Windows)

可以使用下面SQL语句找到对应的操作系统进程SPID,然后杀掉。当然杀掉操作系统进程是一件危险的事情,尤其不要误杀。所以在执行前,一定要谨慎确认。


[code]
[code]SETLINESIZE100

COLUMNspidFORMATA10

COLUMNusernameFORMATA10

COLUMNprogramFORMATA45


SELECTs.inst_id,

s.sid,

s.serial#,

p.spid,

s.username,

s.program

FROMgv$sessions

JOINgv$processpONp.addr=s.paddrANDp.inst_id=s.inst_id

WHEREs.type!='BACKGROUND';

[/code]
[/code]

在数据库如果要彻底杀掉一个会话,尤其是大事务会话,最好是使用ALTERSYSTEMDISCONNECTSESSIONIMMEDIATE或使用下面步骤:

1:首先在操作系统级别Kill掉进程。

2:在数据库内部KILLSESSION

或者反过来亦可。这样可以快速终止进程,释放资源。

参考资料:

http://www.eygle.com/faq/Kill_Session.htm

http://www.oracle-base.com/articles/misc/killing-oracle-sessions.php#unix

http://www.eygle.com/archives/2005/10/oracle_howto_kill_session.html

http://blog.sina.com.cn/s/blog_6d6e54f70100zfqp.html

http://docs.oracle.com/cd/B28359_01/server.111/b28286/statements_2013.htm#SQLRF53047
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: