3/05/2008

About Lock

有关视图
v$session 查询会话的信息
v$session_wait 查询等待的会话信息
v$lock 列出系统中的所有锁
dba_locks 对v$lock的格式化视图
v$locked_object 只包含DML的锁信息,包括回滚段和会话信息


例:怎么杀掉特定的数据库会话
Alter system kill session 'sid,serial#';
或者
alter system disconnect session 'sid,serial#' immediate;
在win上,还可以采用oracle提供的orakill杀掉一个线程(其实就是一个Oracle进程)在Linux/Unix上,可以直接利用kill杀掉数据库进程对应的OS进程

例:怎么快速查找锁与锁等待
数据库的锁是比较耗费资源的,特别是发生锁等待的时候,我们必须找到发生等待的锁,有可能的话,杀掉该进程。

这个语句将查找到数据库中所有的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



如果发生了锁等待,我们可能更想知道是谁锁了表而引起谁的等待以下的语句可以查询到谁锁了表,而谁在等待。
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$rollname,其中xidusn就是回滚段的USN

例:查询锁的状况的对象有
  V$LOCK, V$LOCKED_OBJECT, V$SESSION, V$SQLAREA, V$PROCESS ;
例:查询锁的表的方法
SELECT S.SID SESSION_ID,S.USERNAME,DECODE(LMODE,0,'None',1,'Null',2,'Row-S (SS)',3,'Row-X (SX)',4,'Share',5,'S/Row-X (SSX)',6,'Exclusive',TO_CHAR(LMODE)) MODE_HELD,DECODE(REQUEST,0,'None',1,'Null',2,'Row-S (SS)',3,'Row-X (SX)',4,'Share',5,'S/Row-X (SSX)',6,'Exclusive',TO_CHAR(REQUEST)) MODE_REQUESTED,O.OWNER'.'O.OBJECT_NAME' ('O.OBJECT_TYPE')',S.TYPE LOCK_TYPE,L.ID1 LOCK_ID1,L.ID2 LOCK_ID2 FROM V$LOCK L,SYS.DBA_OBJECTS O,V$SESSION S WHERE L.SID = S.SID AND L.ID1 = O.OBJECT_ID ;
例:如何解锁?
  ALTER SYSTEM KILL SESSION ‘SID,SERIR#’;
例:如何监控当前数据库谁在运行什么SQL语句?
  SELECT osuser, username, sql_text from v$session a, v$sqltext b
  where a.sql_address =b.address order by address, piece;


例:锁中字段代码含义

type
TX 锁定行
TM 表锁定

lmode
1 NULL
2 行共享
3 行排他
4 共享
5 共享行排他
6 排他

例:谁被锁住?
Select a.sid,a.serial#,a.username,A.LOCKWAIT,a.status,a.program,b.name
from v$session a,audit_actions b
where a.command=b.action
AND LOCKWAIT IS NOT NULL;
例:谁在锁表?
Select a.sid,a.serial#,a.username,A.LOCKWAIT,a.status,a.program,b.name
from v$session a,audit_actions b
where a.command=b.action
AND STATUS=ACTIVE;



单用户数据库或许从来就不需要锁,但是在一个多用户的环
境,有一个合适地自动满足数据的并行性、一致性和完整性的
机制是非常重要的。Oracle是通过使用一个内部锁定机制来维
护数据的完整性、并行性和一致性。

ORACLE有两种级别的锁
共享锁(Share Lock)
为数据存取的高并行性提供保证。
专用锁(Exclusive Lock)
防止同时共享资源。例如一个事务获得了某一资源的专用锁,那么直到该锁被解锁,其他事务才能修改那个资源。


ORACLE锁按类型可分为两种不同的锁:
数据锁(DML LOCK)
在表中获得并且保护数据,从根本上说是保护数据的完整性
字典锁(DDL LOCK)
用于保护对象的结构如表、视图和索引的定义。在获得DDL数据定义事务时,字典锁将自动获得。


数据锁
当用户对表格中数据执行insert、update和delete操作时,会自动获得数据锁,它用来保护数据的一致性。按级别可分行级锁、表级锁。
DML语句会获得两种类型的锁结构:
表上的共享锁正在更改每一行的专用锁

例如:update emp set sal=8888 where empno=7788;

注意:假如有多个用户同时对一行进行修改,他们都会获得共享的表锁,但只有一个最先请求锁的用户才可获得行专用锁。

字典锁
当用户创建、修改或者删除表时将要用到字典锁。它通常是表级别锁,用来防止两个用户同时修改同一个表的结构。
专用DDL锁:
当诸如create,alter和drop这样的语句用于一个对象时,使用此锁。
共享DDL锁:
当诸如grant和create package这样的语句用于一个对象时,使用此锁。
 

手工锁定
假如你要执行一张表中列值的全局更新并且希望事务对该表进行单独存取,以便事务不必等待其他事务的完成该表的操作,那么可以通过人工锁定的该表以防止其他事务获得该表中 的锁。
共享锁
例如:lock table emp in share mode;
独享锁
例如:lock table emp in exclusive mode;
查询时也可手工锁定查询集
例如:select * from emp
where deptno=10
update for;

例如 SELECT fffs FROM fffs WHERE fffs='01'
FOR UPDATE OF fffs NOWAIT;
 

死锁
死锁是指两个或多个用户多在等待被彼此相互锁定的同一数据而形成的一种局面。例如:
用户A:update emp set sal=8888 where empno=7788;

在该软件中可以直接查询锁,杀掉进程,下载地址

No comments: