通过几个步骤有效关闭Oracle死锁进程,和释放状态为killed的session
有效关闭Oracle死锁进程的具体步骤:
1.查哪个过程被锁
查V$DB_OBJECT_CACHE视图:
SELECT * FROM V$DB_OBJECT_CACHE WHERE OWNER=’过程的所属用户’ AND LOCKS!=’0′;
V$DB_OBJECT_CACHE
This view displays database objects that are cached in the library cache. Objects include tables, indexes, clusters, synonym definitions, PL/SQL procedures and packages, and triggers.
| Column | Datatype | Description |
|---|---|---|
OWNER |
VARCHAR2(64) |
Owner of the object |
NAME |
VARCHAR2(1000) |
Name of the object |
DB_LINK |
VARCHAR2(64) |
Database link name, if any |
NAMESPACE |
VARCHAR2(28) |
Library cache namespace of the object: TABLE/PROCEDURE, BODY, TRIGGER, INDEX, CLUSTER, OBJECT |
TYPE |
VARCHAR2(28) |
Type of the object: INDEX, TABLE, CLUSTER, VIEW, SET, SYNONYM, SEQUENCE, PROCEDURE, FUNCTION, PACKAGE, PACKAGE BODY, TRIGGER, CLASS, OBJECT, USER, DBLINK |
SHARABLE_MEM |
NUMBER |
Amount of sharable memory in the shared pool consumed by the object |
LOADS |
NUMBER |
Number of times the object has been loaded. This count also increases when an object has been invalidated. |
EXECUTIONS |
NUMBER |
Not usedSee Also: “V$SQLAREA” to see actual execution counts |
LOCKS |
NUMBER |
Number of users currently locking this object |
PINS |
NUMBER |
Number of users currently pinning this object |
KEPT |
VARCHAR2(3) |
(YES | NO) Depends on whether this object has been “kept” (permanently pinned in memory) with the PL/SQL procedure DBMS_SHARED_POOL.KEEP |
CHILD_LATCH |
NUMBER |
Child latch number that is protecting the object |
INVALIDATIONS |
NUMBER |
Total number of times objects in the namespace were marked invalid because a dependent object was modified |
2. 查是哪一个SID,通过SID可知道是哪个SESSION
查V$Access视图:
SELECT * FROM V$ACCESS WHERE OWNER=’过程的所属用户’ AND NAME=’刚才查到的过程名’;
V$ACCESS
V$ACCESS displays information about locks that are currently imposed on library cache objects. The locks are imposed to ensure that they are not aged out of the library cache while they are required for SQL execution.
| Column | Datatype | Description |
|---|---|---|
SID |
NUMBER |
Session number that is accessing an object |
OWNER |
VARCHAR2(64) |
Owner of the object |
OBJECT |
VARCHAR2(1000) |
Name of the object |
TYPE |
VARCHAR2(24) |
Type identifier for the object |
3. 查出SID和SERIAL#
查V$SESSION视图:
SELECT SID,SERIAL#,PADDR FROM V$SESSION WHERE SID=’刚才查到的SID’
查V$PROCESS视图:
SELECT SPID FROM V$PROCESS WHERE ADDR=’刚才查到的PADDR‘;
4. 杀进程
(1).先杀Oracle进程:
ALTER SYSTEM KILL SESSION ‘查出的SID,查出的SERIAL#’;
(2).再杀操作系统进程:
KILL -9 刚才查出的SPID
或者用ORAKILL(刚才查出的SID和SPID)。
在日常的学习和工作中,我们经常会遇到一个问题是:在Oracle中,状态已被置为”killed“的进程长时间锁定系统资源,不释放,有一个比重启数据库更好的方法,就是在操作系统级强行杀掉那些进程。
1.下面的语句用来查询哪些对象被锁:
col object_name for a30
col machine for a20
select object_name,machine,s.sid,s.serial#
from v$locked_object l,dba_objects o ,v$session s
where l.object_id = o.object_id and l.session_id=s.sid;
|
V$LOCKED_OBJECT
This view lists all locks acquired by every transaction on the system. It shows which sessions are holding DML locks (that is, TM-type enqueues) on what objects and in what mode.
| Column | Datatype | Description |
|---|---|---|
XIDUSN |
NUMBER |
Undo segment number |
XIDSLOT |
NUMBER |
Slot number |
XIDSQN |
NUMBER |
Sequence number |
OBJECT_ID |
NUMBER |
Object ID being locked |
SESSION_ID |
NUMBER |
Session ID |
ORACLE_USERNAME |
VARCHAR2(30) |
Oracle user name |
OS_USER_NAME |
VARCHAR2(30) |
OS user name |
PROCESS |
VARCHAR2(12) |
OS process ID |
LOCKED_MODE |
NUMBER |
Lock mode |
2.下面的语句用来杀死一个进程:
alter system kill session '42,21993'; (其中24,111分别是上面查询出的sid,serial#) |
可以用如下查询批量得到上面类似的语句:
select 'alter system kill session ''' ||s.sid||','||s.serial#||'''; ' from v$locked_object l,dba_objects o ,v$session s where l.object_id = o.object_id and l.session_id=s.sid |
;
3.如果利用上面的命令杀死一个进程后,进程状态被置为 “killed”, 但是锁定的资源很长时间没有被释放,那么可以在os一级再杀死相应的进程(线程),首先获得进程(线程)号:
select spid, osuser, s.program from v$session s,v$process p where s.paddr=p.addr and s.sid=#sid; (#sid是上面的sid) |
4.在操作系统中杀掉相应的进程(线程):
(1)在Linux上,用root身份执行命令:
kill -9 12345(12345是第3步查询出的spid)
(2)在Windows 用orakill杀死线程,orakill是oracle提供的一个可执行命令,语法为:orakill sid thread
其中:
sid:表示要杀死的进程属于的实例名
thread:是要杀掉的线程号,即第3步查询出的spid。
例:c:>orakill orcl 12345
注:可以写一个组合查询的存储过程来自动执行上述四步操作,方便地杀光所有不自动释放资源的进程,但一般情况下不推荐这样做,毕竟在系统中用root用户kill进程本身就是有一定的风险的!