
Oracle动态性能视图学习之v$lock.doc
6页Oracle 动态性能视图学习之 v$lock & v$locked_object这个视图列出Oracle服务器当前拥有的锁以及未完成的锁或栓锁请求如果你觉着 session在等待等待事件队列那你应该检查本视图如果你发现session在等待一个锁,那 么按如下先后顺序:使用V$LOCK找出session持有的锁使用V$SESSION找出持有锁或等待锁的session执行的sql语句使用V$SESSION_WAIT找出什么原因导致session持有锁堵塞使用V$SESSION获取关于持有锁的程序和用户的更多信息V$LOCK中的常用列SID:表示持有锁的会话信息TYPE:表示锁的类型值包括TM和TX等LMODE:表示会话等待的锁模式的信息用数字0 — 6表示,和表1相对应REQUEST:表示session请求的锁模式的信息ID1, ID2:表示锁的对彖标识公共锁类型在Oracle数据库中,DML锁主要包括TM锁和TX锁,其中TM锁称为表级锁,TX锁称为事务 锁或行级锁当Oracle执行DML语句时,系统自动在所要操作的表上申请TM类型的锁当TM锁获得后, 系统再自动申请TX类型的锁,并将实际锁定的数据行的锁标志位进行置位。
这样在事务加 锁前检查TX锁相容性时就不用再逐行检查锁标志,而只需检查TM锁模式的相容性即可,大 大提高了系统的效率TM锁包括了 SS、SX、S、X等多种模式,在数据库中用0 — 6来表示 不同的SQL操作产生不同类型的TH锁,如下表1TX:行级锁,事务锁在改变数据时必须是排它模式(mode 6)每一个活动事务都拥有一个锁它将在事务结束 (commi t/rol lback)时释放如果一个块包括的列被改变而没有ITL(interested transact io n list)槽位(entries),那么 session 将锁置于共享模式(mode 4) o 当 session 获得块的ITL槽位时释放当一个事务首次发起一个DML语句时就获得一个TX锁,该锁保 持到事务被提交或回滚当两个或多个会话在表的同一条记录上执行DML语句时,第一个会 话在该条记录上加锁,其他的会话处于等待状态当第一个会话提交后,TX锁被释放,其 他会话才可以加锁指出冋滚段和事务表项按下列项以避免竞争:避免TX-6类型竞争,需要根据您的应用而定避免TX-4类型竞争,可以考虑增加对彖INITRANS参数值TM:表级锁数据库执行任何DDL语句时必须是排它模式;例如alter table, drop table。
执行像 insert, update, delete这类DML语句时处于共享模式它防止其它session对同一个对象 同时执行ddl语句任何对象拥有正被改变的数据,TM锁都将必须存在锁指向对象在 TM队列避免竞争,可以考虑屏蔽对彖表级锁,屏蔽表级锁防止对象执行任何ddl语句ST:空间事务锁每个数据库(非实例)拥有一个ST锁除了本地管理表空间,在space管理操作(新建或删除 extents)时必须是排它模式对象 creation, dropping, extension,以及 truncation 都 处于这种锁多数公共原因的争夺,是在磁盘排序(并非使用真正的临时表空间)或回滚段扩 展或收缩按如下项以避免竞争:使用真正的临时表空间(true temporary tablespaces),利用临时文件临时段在磁盘排序 之后并不创建或删除使用本地管理表空间指定回滚段避免动态扩展和收缩,或使用口动undo managemento避免应用执行创建或删除数据库对象UL:用户定义锁用户可以自定义锁内容较多并与此节关系不大,略过V$LOCK中的连接列ColumnCol urnn(s)SIDID1, ID2, TYPEID1TRUNCID1/65536)V$LOCKViewJoinedV$SESSIONDBA_OBJECTSSIDID1, ID2, TYPEOBJECT_IDV$ROLLNAMEUSX如果session在等待锁,这可被用于找出session持有的锁。
可被用于找出DML锁类型的被 锁对象(type二'TM'),可被用于找出行级事务锁(TYPE二'TX')使用中的回滚段,不过需要通过 V$TRANSACTION连接查询得到表1 Oracle的TM锁类型锁模式锁描述解释SQL操作0none1NULL空Select2SS(Row-S)行级共亨锁,其他对象只能查询 这此数据行Select for update> Lock for update^ Lock row share3SX(Row-X)行级排它锁,在提交前不允许做DML操作Inserts Update. Delete、 Lock row share4S (Share)共享锁Create index、 Lock share5SSX (S/Row-X)共亭行级排它锁Lock share row exclusive6X (Exclusive)排它锁AIter table、 Drop table、 Drop index> Truncate table 、 Lock exclusive数字越大锁级别越高,影响的操作越多一般的查询语句如select... from ...;是小于 2 的锁,有时会在 v$locked_object 出现。
selec t ... from ... for update;是 2 的锁 当对话使用for update子串打开一个游标时,所有返回集中的数据行都将处于行级(Row-X) 独占式锁定,其他对彖只能查询这些数据行,不能进行update、delete或select... for update 操作insert / update / delete ...;是 3 的锁没有commit之前插入同样的一条记录会没有反应,因为后一个3的锁会一直等待上一个3 的锁,我们必须释放掉上一个才能继续工作创建索引的时候也会产生3, 4级别的锁o locked mode为2, 3, 4不影响DML (insert, delete, update, select)操作,但 DDL (alter, drop 等)操作会提示 ora-00054 错 误有主外键约束时update / delete ...;可能会产生4, 5的锁DDL语句时是6的锁如果出现了锁的问题,某个DML操作对能等待很久没有反应当你采用的是直接连接数据库 的方式,也不要用OS系统命令$kill process_num或者$kill -9 process_num來终止用 户连接,因为一个用户进程可能产生一个以上的锁,杀OS进程并不能彻底清除锁的问题。
记得在数据库级别用alter system kill session ' sid, serial#';杀掉不正常的锁示例:我按照自己的理解演示的TX, TM锁如下:1. create table TMPKcoll VARCIIAR2 (50))创建临时表2. select * from v$lock; --关掉当前锁信息3. select * from tmpl for update; ―力口锁4. select * from v$lock;―看看现在的锁列表,是不是多了两条记录Type分别为tx, tm, 对照表lo5. 新开一个连接,然后select * from tmpl for update;—呵呵,等待状态了吧select * from v$lock; --又新增了两条记录,其它一条 type=tx, lmode=07. 查看当前被锁的session正在执行的sql语句SQL> select /*+N0_MERGE(a) NO_MERGE(b) NO_MERGE(c) */ a. username, a. machine, a. sid, a. serial#, a. last_call_et "Seconds〃,b. idl, c. sql_text "SQL"from v$session a, v$lock b, v$sqItext cwhere a. username is not null and a. lockwait = b. kaddrand c. hash_value =a. sql_hash_value8. 将之前的for update语句commit或者rollback,然后新开连接的session拥有锁。
有 兴趣的朋友还可以试试两条for update的时候,关闭先执行的那个窗口,看看oracle会给 出什么样的响应这一节是我在自整理此系列视图以来花费时间和精力最多的一个,我反复看了 document, 又从网上搜索了各种资料实际使用案例等,就是不开窍这一节至今我也仍未有把握说尽在 掌握,所以在上述文字中除了例子,我如实贴出了收集来的内容,未加任何自我理解,就是 担心万一我的理解有误,会对其它浏览本文的人造成困扰同时我把在收集过程中自我感觉 对理解v$lock可能有帮助的资料地址列岀,供有心人参考:Oracle数据库中的锁机制研究http://soft. zdnet. com. cn/software zone/2007/0208/377403. shtmlDB2和Oracle的并发控制(锁)比较http://www. ibm. com/deve1operworks/cn/db2/library/1echarticles/dm-0512niuxzh/Itpub论坛的oracle专题深入讨论区也有一篇非常精彩的讨论,地址如下:我对ORACLE数据锁的一点体会http://www. itpub. net/270059. html本视图列出系统上的每个事务处理所获得的所有锁。
V$LOCKED_OBJECT 中的列说明:XIDUSN:回滚段号XIDSLOT:槽号XIDSQN:序列号OBJECT ID:被锁对象IDSESSION ID:持有锁的 scssionlDORACLE USERNAME:持有锁的Oracle用户名OS_USER_NAME:持有锁的操作系统用户名PROCESS:操作系统进程号LOCKED MODE:锁模式,值同上表1示例:以DBA角色,查看当前数据库里锁的情况可以用如下SQL语句:SQL> sclect object id,session id,locked mode from v$lockcd object;SQL> sclect t2・ username, t2・ sid, t2・ serial#, t2・ 1 ogon timefrom v$locked object tl, v$scssion t2where tl・ session id = t2・ sidorder by t2・ logon time;如果有长期出现的一列,可能是没有释放的锁我们可以用下而SQL语句杀掉长 期没有释放非正常的锁:SQL> alter system kill session J sid,serial#5 ;。
