下午接到一个用户反馈的问题,新闻流程无法提交结案时一直处于等待状态没有响应。不久,梁姐说应该是数据表被锁死了导致的。后来查询了系统日志,确实有死错的报错(ORA-00060)。比较犀利的DBA离职了,只得帮他们弄了。于是设法手工操作数据库,解除锁定。经过一番折腾,终于搞定。——不够专业,没办法,呵呵。

查询v$session s,v$lock l,dba_objects 表,取得需要解锁记录的session_id和serial。查询到我们的死锁记录锁类型为3级锁(Row-X ,行专用(RX),用于行的修改),锁定了相应表的行记录。

然后执行 alter system kill session ‘sid,serial#’  SQL语句。

 至于为什么导致锁无法释放,查找资料后可能性比较高的是:某些操作异常,导致数据库操作事务的操作没结束事务(rollback/commit),导致锁无法释放。

========================

转载一些查锁的资料:

Oracle的锁表与解锁

SELECT /*+ rule */ s.username,
decode(l.type,’TM’,’TABLE LOCK’,
‘TX’,’ROW LOCK’,
NULL) LOCK_LEVEL,
o.owner,o.object_name,o.object_type,
s.sid,s.serial#,s.terminal,s.machine,s.program,s.osuser
FROM v$session s,v$lock l,dba_objects o
WHERE l.sid = s.sid
AND l.id1 = o.object_id(+)
AND s.username is NOT Null

–kill session语句
alter system kill session’50,492′;
–以下几个为相关表
SELECT * FROM v$lock;
SELECT * FROM v$sqlarea;
SELECT * FROM v$session;
SELECT * FROM v$process ;
SELECT * FROM v$locked_object;
SELECT * FROM all_objects;
SELECT * FROM v$session_wait;
–1.查出锁定object的session的信息以及被锁定的object名
SELECT l.session_id sid, s.serial#, l.locked_mode,l.oracle_username,
l.os_user_name,s.machine, s.terminal, o.object_name, s.logon_time
FROM v$locked_object l, all_objects o, v$session s
WHERE l.object_id = o.object_id
AND l.session_id = s.sid
ORDER BY sid, s.serial# ;
–2.查出锁定表的session的sid, serial#,os_user_name, machine name, terminal和执行的语句
–比上面那段多出sql_text和action
SELECT l.session_id sid, s.serial#, l.locked_mode, l.oracle_username, s.user#,
l.os_user_name,s.machine, s.terminal,a.sql_text, a.action
FROM v$sqlarea a,v$session s, v$locked_object l
WHERE l.session_id = s.sid
AND s.prev_sql_addr = a.address
ORDER BY sid, s.serial#;
–3.查出锁定表的sid, serial#,os_user_name, machine_name, terminal,锁的type,mode
SELECT s.sid, s.serial#, s.username, s.schemaname, s.osuser, s.process, s.machine,
s.terminal, s.logon_time, l.type
FROM v$session s, v$lock l
WHERE s.sid = l.sid
AND s.username IS NOT NULL
ORDER BY sid;

这个语句将查找到数据库中所有的DML语句产生的锁,还可以发现,
任何DML语句其实产生了两个锁,一个是表锁,一个是行锁。
杀锁命令
alter system kill session ‘sid,serial#’
SELECT /*+ rule */ s.username,
decode(l.type,’TM’,’TABLE LOCK’,
‘TX’,’ROW LOCK’,
NULL) LOCK_LEVEL,
o.owner,o.object_name,o.object_type,
s.sid,s.serial#,s.terminal,s.machine,s.program,s.osuser
FROM v$session s,v$lock l,dba_objects o
WHERE l.sid = s.sid
AND l.id1 = o.object_id(+)
AND s.username is NOT NULL
如果发生了锁等待,我们可能更想知道是谁锁了表而引起谁的等待
以下的语句可以查询到谁锁了表,而谁在等待。
以上查询结果是一个树状结构,如果有子节点,则表示有等待发生。
如果想知道锁用了哪个回滚段,还可以关联到V$rollname,其中xidusn就是回滚段的USN
col user_name format a10
col owner format a10
col object_name format a10
col object_type format a10
SELECT /*+ rule */ lpad(‘ ‘,decode(l.xidusn ,0,3,0))||l.oracle_username User_name,
o.owner,o.object_name,o.object_type,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
ORDER BY o.object_id,xidusn DESC

使用v$session视图获取hang住会话的sid和serial#
SYS@prod>select sid,serial#,username from v$session where sid in (select blocking_session from v$session);

SID SERIAL# USERNAME

———- ———- ——————————
5 HR

找到hang住的会话后,执行alter system命令kill掉相应的session就可以了:
SYS@prod>alter system kill session ‘159,5’ immediate;

— 返回:System altered.

v$locked_object
XIDUSN undo segment number , 可以和v$transaction关联
XIDSLOT undo slot number
XIDSQN 序列号
OBJECT_ID 被锁定对象的object_id , 可以和dba_objects关联
SESSION_ID 持有该锁的session_id, 可以和v$session关联
ORACLE_USERNAME 持有该锁的oracle帐号
OS_USER_NAME 持有该锁的操作系统帐号
PROCESS 操作系统的进程号,可以和v$process关联
LOCKED_MODE 锁模式,含义同v$lock.lmode

Dba_locks 和v$lock 内容差不多,略

V$session 如果某个session被因为某些行被其他会话锁定而阻塞,则该视图中的下面四个字段列出了这些行所属对象的相关信息
ROW_WAIT_FILE# 等待的行所在的文件号
ROW_WAIT_OBJ# 等待的行所属的object_id
ROW_WAIT_BLOCK# 等待的行所属的block
ROW_WAIT_ROW# 等待的行在blcok中的位置

v$lock
SID 会话的sid,可以和v$session 关联
TYPE 区分该锁保护对象的类型,如tm,tx,rt,mr等
ID1 锁表示1
ID2 锁表示2
LMODE 锁模式,见下面说明
REQUEST 申请的锁模式,同lmode
CTIME 已持有或者等待锁的时间
BLOCK 是否阻塞其他会话锁申请 1:阻塞 0:不阻塞

LMODE取值0,1,2,3,4,5,6, 数字越大锁级别越高, 影响的操作越多。
1级锁:
Select,有时会在v$locked_object出现。
2级锁即RS锁
相应的sql有:Select for update ,Lock xxx in Row Share mode,select for update当对
话使用for update子串打开一个游标时,所有返回集中的数据行都将处于行级(Row-X)独
占式锁定,其他对象只能查询这些数据行,不能进行update、delete或select for update
操作。
3级锁即RX锁
相应的sql有:Insert, Update, Delete, Lock xxx in Row Exclusive mode,没有commit
之前插入同样的一条记录会没有反应, 因为后一个3的锁会一直等待上一个3的锁, 我们
必须释放掉上一个才能继续工作。
4级锁即S锁
相应的sql有:Create Index, Lock xxx in Share mode
5级锁即SRX锁
相应的sql有:Lock xxx in Share Row Exclusive mode,当有主外键约束时update
/delete … ; 可能会产生4,5的锁。
6级锁即X锁
相应的sql有:Alter table, Drop table, Drop Index, Truncate table, Lock xxx in Exclusive
mode

ID1,ID2的取值含义根据type的取值而有所不同
对于TM 锁
ID1表示被锁定表的object_id 可以和dba_objects视图关联取得具体表信息,ID2 值为0
对于TX 锁
ID1以十进制数值表示该事务所占用的回滚段号和事务槽slot number号,其组形式:
0xRRRRSSSS,RRRR=RBS/UNDO NUMBER,SSSS=SLOT NUMBER
ID2 以十进制数值表示环绕wrap的次数,即事务槽被重用的次数