Oracle学习动态性能表(二)

2014-11-24 09:26:04 · 作者: · 浏览: 1
r update操作。insert / update / delete ... ; 是3的锁。

没有commit之前插入同样的一条记录会没有反应,因为后一个3的锁会一直等待上一个3的锁,我们必须释放掉上一个才能继续工作。

创建索引的时候也会产生3,4级别的锁。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 TMP1(col1 VARCHAR2(50));--创建临时表
2.select * from v$lock; --关掉当前锁信息
3.select * from tmp1 for update; --加锁
4.select * from v$lock; --看看现在的锁列表,是不是多了两条记录。Type分别为tx,tm,对照表1。
5.新开一个连接,然后
select * from tmp1 for update; --呵呵,等待状态了吧
select * from v$lock; --又新增了两条记录,其它一条type=tx,lmode=0
7.查看当前被锁的session正在执行的sql语句
SQL> select /*+ NO_MERGE(a) NO_MERGE(b) NO_MERGE(c) */ a.username, a.machine, a.sid, a.serial#, a.last_call_et "Seconds", b.id1, c.sql_text "SQL"
from v$session a, v$lock b, v$sqltext c
where a.username is not null and a.lockwait = b.kaddr
and c.hash_value =a.sql_hash_value
8.将之前的for update语句commit或者rollback,然后新开连接的session拥有锁。有兴趣的朋友还可以试试两条for update的时候,关闭先执行的那个窗口,看看oracle会给出什么样的响应。

这一节是我在自整理v$系列视图以来花费时间和精力最多的一个,我反复看了document,又从网上搜索了各种资料实际使用案例等,就是不开窍。这一节至今我也仍未有把握说尽在掌握,所以在上述文字中除了例子,我如实贴出了收集来的内容,未加任何自我理解,就是担心万一我的理解有误,会对其它浏览本文的人造成困扰。同时我把在收集过程中自我感觉对理解v$lock可能有帮助的资料地址列出,供有心人参考:

Oracle数据库中的锁机制研究
http://soft.zdnet.com.cn/software_zone/2007/0208/377403.shtml

DB2和 Oracle的并发控制(锁)比较
http://www.ibm.com/developerworks/cn/db2/library/techarticles/dm-0512niuxzh/

Itpub论坛的oracle专题深入讨论区也有一篇非常精彩的讨论,地址如下:

我对ORACLE数据锁的一点体会
http://www.itpub.net/270059.html

oracle动态性能表 v$process

本视图包含当前系统oracle运行的所有进程信息。常被用于将oracle或服务进程的操作系统进程ID与数据库session之间建立联系。在某些情况下非常有用:

1.如果数据库瓶颈是系统资源(如:cpu,内存),并且占用资源最多的用户总是停留在某几个服务进程,那么进行如下诸项:

1>.找出资源进程
2>.找出它们的session,你必须将进程与会话联系起来。
3>.找出为什么session占用了如此多的资源

2.SQL跟踪文件名是基于服务进程的操作系统进程ID。要找出session的跟踪文件,你必须将session与服务进程联系起来。
3.某些事件,如rdbms ipc reply,鉴别session进程的Oracle进程ID在等什么。要发现这些进程在做什么,你必须找出它们的session。
4.你所看到的服务器上的后台进程(DBWR,LGWR,PMON等)都是服务进程。要想知道他们在做什么,你必须找到他们的session。

V$PROCESS中的常用列
ADDR:进程对象地址
PID:oracle进程ID
SPID:操作系统进程ID

V$PROCESS中的连接列
Column View Joined Column(s)
ADDR V$SESSION PADDR

示例:
1.查找指定系统用户在oracle中的session信息及进程id,假设操作系统用户为:junsansi
select s.sid,s.SERIAL#, s.username,p.spid
from v$session s, v$process p
where s.osuser = 'junsansi'
and s.PADDR = p.ADDR

2.查看锁和等待
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#,p.spid
FROM v$locked_object l, dba_objects o, v$session s, v$process p
WHERE l.object_id = o.object_id
AND l.session_id = s.sid and s.paddr = p.addr
ORDER BY o.object_id, xidusn DESC

附注:
  在linux环境可以通过ps查看进程信息包括pid,windows中任务管理器的PID与v$process中pid不能一一对应,这块在oracleDocument中也没有找到介绍,后来google了一下,有资料介绍说是由于windows是多线程服务器,每个进程包含一系列线程。这点于unix等不同,Unix每个Oralce进程独立存在,在Nt上所有线程由Oralce进程衍生。
  要在windows中显示oracle相关进程pid,我们可以通过一个简单的sql语句来实现。
SELECT s.SID, p.pid, p.spid signaled, s.osuser, s.program
FROM v$process p, v$session s
WHERE p.addr = s.paddr;

SID PID SIGNALED OSUSER PROGRAM
1 2 2452 SYSTEM ORACLE.EXE
2 3 2460 SYSTEM ORACLE.EXE
3 4 2472 SYSTEM ORACLE