创建博客 登录  
 加关注
   显示下一条  |  关闭

冰冷的夜

 
 
 

日志

 
 

oracle 动态性能表(2)  

2010-03-16 17:14:59|  分类: oracle |  标签: |字号 订阅

 

第四篇-(2)-V$SQLAREA 2007.5.29

  本视图持续跟踪所有shared pool中的共享cursor,在shared pool中的每一条SQL语句都对应一列。本视图在分析SQL语句资源使用方面非常重要。

V$SQLAREA中的信息列

l         HASH_VALUE:SQL语句的Hash值。

l         ADDRESS:SQL语句在SGA中的地址。

这两列被用于鉴别SQL语句,有时,两条不同的语句可能hash值相同。这时候,必须连同ADDRESS一同使用来确认SQL语句。

l         PARSING_USER_ID:为语句解析第一条CURSOR的用户

l         VERSION_COUNT:语句cursor的数量

l         KEPT_VERSIONS:

l         SHARABLE_MEMORY:cursor使用的共享内存总数

l         PERSISTENT_MEMORY:cursor使用的常驻内存总数

l         RUNTIME_MEMORY:cursor使用的运行时内存总数。

l         SQL_TEXT:SQL语句的文本(最大只能保存该语句的前1000个字符)。

l         MODULE,ACTION:使用了DBMS_APPLICATION_INFO时session解析第一条cursor时的信息

V$SQLAREA中的其它常用列

l         SORTS: 语句的排序数

l         CPU_TIME: 语句被解析和执行的CPU时间

l         ELAPSED_TIME: 语句被解析和执行的共用时间

l         PARSE_CALLS: 语句的解析调用(软、硬)次数

l         EXECUTIONS: 语句的执行次数

l         INVALIDATIONS: 语句的cursor失效次数

l         LOADS: 语句载入(载出)数量

l         ROWS_PROCESSED: 语句返回的列总数

V$SQLAREA中的连接列

Column                                                     View                                                                                Joined Column(s)

HASH_VALUE, ADDRESS                   V$SESSION                                                       SQL_HASH_VALUE, SQL_ADDRESS

HASH_VALUE, ADDRESS                   V$SQLTEXT, V$SQL, V$OPEN_CURSOR   HASH_VALUE, ADDRESS

SQL_TEXT                                 V$DB_OBJECT_CACHE                                           NAME

示例:

1.查看消耗资源最多的SQL:

SELECT hash_value, executions, buffer_gets, disk_reads, parse_calls

 FROM V$SQLAREA

 WHERE buffer_gets > 10000000OR disk_reads > 1000000

 ORDERBY buffer_gets + 100 * disk_reads DESC;

2.查看某条SQL语句的资源消耗:

SELECT hash_value, buffer_gets, disk_reads, executions, parse_calls

 FROM V$SQLAREA

 WHERE hash_Value = 228801498AND address = hextoraw('CBD8E4B0');

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

第五篇--V$SESSION 

  在本视图中,每一个连接到数据库实例中的session都拥有一条记录。包括用户session及后台进程如DBWR,LGWR,arcchiver等等。

V$SESSION中的常用列

 

V$SESSION是基础信息视图,用于找寻用户SID或SADDR。不过,它也有一些列会动态的变化,可用于检查用户。如例:

SQL_HASH_VALUE,SQL_ADDRESS:这两列用于鉴别默认被session执行的SQL语句。如果为null或0,那就说明这个session没有执行任何SQL语句。PREV_HASH_VALUE和PREV_ADDRESS两列用来鉴别被session执行的上一条语句。

注意:当使用SQL*Plus进行选择时,确认你重定义的列宽不小于11以便看到完整的数值。

STATUS:这列用来判断session状态是:

l               Achtive:正执行SQL语句(waiting for/using a resource)

l               Inactive:等待操作(即等待需要执行的SQL语句)

l               Killed:被标注为删除

下列各列提供session的信息,可被用于当一个或多个combination未知时找到session。

Session信息

l               SID:SESSION标识,常用于连接其它列

l               SERIAL#:如果某个SID又被其它的session使用的话则此数值自增加(当一个         SESSION结束,另一个SESSION开始并使用了同一个SID)。

l               AUDSID:审查session ID唯一性,确认它通常也用于当寻找并行查询模式

l               USERNAME:当前session在oracle中的用户名。

Client信息

数据库session被一个运行在数据库服务器上或从中间服务器甚至桌面通过SQL*Net连接到数据库的客户端进程启动,下列各列提供这个客户端的信息

l               OSUSER:客户端操作系统用户名

l               MACHINE:客户端执行的机器

l               TERMINAL:客户端运行的终端

l               PROCESS:客户端进程的ID

l               PROGRAM:客户端执行的客户端程序

要显示用户所连接PC的 TERMINAL、OSUSER,需在该PC的ORACLE.INI或Windows中设置关键字TERMINAL,USERNAME。

Application信息

调用DBMS_APPLICATION_INFO包以设置一些信息区分用户。这将显示下列各列。

l               CLIENT_INFO:DBMS_APPLICATION_INFO中设置

l               ACTION:DBMS_APPLICATION_INFO中设置

l               MODULE:DBMS_APPLICATION_INFO中设置

下列V$SESSION列同样可能会被用到:

l               ROW_WAIT_OBJ#

l               ROW_WAIT_FILE#

l               ROW_WAIT_BLOCK#

l               ROW_WAIT_ROW#

V$SESSION中的连接列

Column                                                                           View                                                           Joined Column(s)

SID                V$SESSION_WAIT,,V$SESSTAT,,V$LOCK,V$SESSION_EVENT,V$OPEN_CURSOR                SID

(SQL_HASH_VALUE, SQL_ADDRESS)                  V$SQLTEXT, V$SQLAREA, V$SQL(HASH_VALUE, ADDRESS)

(PREV_HASH_VALUE, PREV_SQL_ADDRESS)     V$SQLTEXT, V$SQLAREA, V$SQL(HASH_VALUE, ADDRESS)

TADDR                                                                            V$TRANSACTION                                     ADDR

PADDR                                                                            V$PROCESS                                             ADDR

示例:

1.查找你的session信息

SELECT SID, OSUSER, USERNAME, MACHINE, PROCESS

 FROM V$SESSION WHERE audsid = userenv('SESSIONID');

2.当machine已知的情况下查找session

SELECT SID, OSUSER, USERNAME, MACHINE, TERMINAL

 FROM V$SESSION

 WHERE terminal = 'pts/tl'AND machine = 'rgmdbs1';

3.查找当前被某个指定session正在运行的sql语句。假设sessionID为100

select b.sql_text

 from v$session a,v$sqlarea b

 where a.sql_hash_value=b.hash_valueand a.sid=100

寻找被指定session执行的SQL语句是一个公共需求,如果session是瓶颈的主要原因,那根据其当前在执行的语句可以查看session在做些什么。

 

 

 

 

 

 

 

 

 

第六篇-(1)-V$SESSION_WAIT 

  这是一个寻找性能瓶颈的关键视图。它提供了任何情况下session在数据库中当前正在等待什么(如果session当前什么也没在做,则显示它最后的等待事件)。当系统存在性能问题时,本视图可以做为一个起点指明探寻问题的方向。

  V$SESSION_WAIT中,每一个连接到实例的session都对应一条记录。

V$SESSION_WAIT中的常用列

 

l         SID: session标识

l         EVENT: session当前等待的事件,或者最后一次等待事件。

l         WAIT_TIME: session等待事件的时间(单位,百分之一秒)如果本列为0,说明session当前session还未有任何等待。

l         SEQ#: session等待事件将触发其值自增长

l         P1, P2, P3: 等待事件中等待的详细资料

l         P1TEXT, P2TEXT, P3TEXT: 解释说明p1,p2,p3事件

附注:

1.State字段有四种含义﹕

(1)Waiting:SESSION正等待这个事件。

(2)Waited unknown time:由于设置了timed_statistics值为false,导致不能得到时间信息。表示发生了等待,但时间很短。

(3)Wait short time:表示发生了等待,但由于时间非常短不超过一个时间单位,所以没有记录。

(4)Waited knnow time:如果session等待然后得到了所需资源,那么将从waiting进入本状态。

2.Wait_time值也有四种含义:

(1)值>0:最后一次等待时间(单位:10ms),当前未在等待状态。

(2)值=0:session正在等待当前的事件。

(3)值=-1:最后一次等待时间小于1个统计单位,当前未在等待状态。

(4)值=-2:时间统计状态未置为可用,当前未在等待状态。

3.Wait_time和Second_in_wait字段值与state相关:

(1)如果state值为Waiting,那么wait_time值无用。Second_in_wait值是实际的等待时间(单位:秒)。

(2)如果state值为Wait unknow time,那么wait_time值和Second_in_wait值都无用。

(3)如果state值为Wait short time,那么wait_time值和Second_in_wait值都无用。

(4)如果state值为Waiting known time,那么wait_time值就是实际等待时间(单位:秒),Second_in_wait值无用。

V$SESSION_WAIT中的连接列

Column            View                Joined Column(s)

SID                 V$SESSION              SID

示例:

1.列出当前系统的等待事件

SELECT event,

       sum(decode(wait_time,0,1,0)) "Curr",

       sum(decode(wait_time,0,0,1)) "Prev",

      count(*)"Total"

 FROM v$session_wait GROUPBY event ORDERBYcount(*);

EVENT                                                     Prev         Curr         Tot

---------------------------------------------        ----           -----         -----

PL/SQL lock timer                                      0              1              1

SQL*Net more data from client           0              1              1

smon timer                                                0              1              1

pmon timer                                                0              1              1

SQL*Net message to client                 2              0              2

db file scattered read                           2              0              2

rdbms ipc message                                     0              7              7

Enqueue                                                    0              12             12

pipe get                                                     0              12             12

db file sequential read                         3              10             13

latch free                                                   9              6              15

SQL*Net message from client             835           13802215

这个按事件和wait_time的分组查询列出下列的信息:

l         多数的session都是空闲事件如:SQL*Net message from client, pipe get, PMON timer等。

l         session的cpu占用可以通过上次session的非等待事件大致算出,除此问题外:看起来多数session没有在等待什么事情(难道他们都在干活?)但其最后等待事件都是SQL*Net message from client。

2.列出指定ID的等待事件

select * from v$session_wait where sid=100;

3.应用p1,p2,p3进行等待事件的分析

v$session_wait视图的列代表的缓冲区忙等待事件如下:

P1—与等待相关的数据文件的全部文件数量。

P2—P1中的数据文件的块数量。

P3—描述等待产生原因的代码。

例:select p1 "File #", p2 "Block #", p3 "Reason Code"

  from v$session_wait

  where event = 'buffer busy waits';

如果以上查询的结果显示一个块在忙等待,以下的查询将显示这一块的名称和类型:

select owner, segment_name, segment_type

 from dba_extents

 where file_id = &P1 and &P2 between block_id and block_id + blocks -1;

  我们也可以查询dba_data_files以确定等待的文件的file_name,方法是使用v$session_wait中的P1。

  从v$session_wait中查询P3(原因编码)的值可以知道session等待的原因。原因编码的范围从0到300,下列为部分编码所代表的事项:

0 块被读入缓冲区。

100 我们想要NEW(创建)一个块,但这一块当前被另一session读入。

110 我们想将当前块设为共享,但这一块被另一session读入,所以我们必须等待read()结束。

120 我们想获得当前的块,但其他人已经将这一块读入缓冲区,所以我们只能等待他人的读入结束。

130 块被另一session读入,而且没有找到其它协调的块,所以我们必须等待读的结束。缓冲区死锁后这种情况也有可能产生。所以必须读入块的CR。

200 我们想新创建一个block,但其他人在使用,所以我们只好等待他人使用结束。

210 Session想读入SCUR或XCUR中的块,如果块交换或者session处于非连续的TX模式,所以等待可能需要很长的时间。

220 在缓冲区查询一个块的当前版本,但有人以不合法的模式使用这一块,所以我们只能等待。

230 以CR/CRX方式获得一个块,但块中的更改开始并且没有结束。

231 CR/CRX扫描找到当前块,但块中的更改开始并且没有结束。

第六篇-(2)-V$SESSION_EVENT 2007.5.30

  本视图记录了每个session的每一项等待事件。由上文所知V$SESSION_WAIT显示了session的当前等待事件,而V$SESSION_EVENT则记录了session自启动起所有的事件。

V$SESSION_EVENT中的常用列

l         SID:session标识

l         EVENT:session等待的事件

l         TOTAL_WAITS:此session当前事件的总等待数

l         TIME_WAITED:此session总等待时间(单位,百分之一秒)

l         AVERAGE_WAIT:此session当前事件平均等待时间(单位,百分之一秒)

l         TOTAL_TIMEOUTS:等待超时次数

其它用法与V$SESSION_WAIT相似,不详述了

附注:

Oracle的等待事件是衡量Oracle运行状况的重要依据及指标。等待事件的概念是在Oracle7.0.1.2中引入的,大致有100个等待事件。在Oracle 8.0中这个数目增加到了大约150个,在Oracle8i中大约有200个事件,在Oracle9i中大约有360个等待事件。主要有两种类别的等待事件,即空闲(idle)等待事件和非空闲(non-idle)等待事件。

关于空闲事件和非空闲事件目前通过google可以搜索到非常多详尽的相关信息,同时

Oracle Database Performance Tuning Guide and Reference中关于Wait Events也有非常详尽的描述,在此就不多费口舌了。不过我在itpub论坛看到有热心人整理的chm格式非空闲事件说明,有兴趣的朋友可以下载,链接如下:

 

 

 

 

 

 

 

 

 

 

第七篇--V$PROCESS 

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

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

l         找出资源进程

l         找出它们的session,你必须将进程与会话联系起来。

l         找出为什么session占用了如此多的资源

2.         SQL跟踪文件名是基于服务进程的操作系统进程ID。要找出session的跟踪文件,你必须将session与服务进程联系起来。

3.         某些事件,如rdbms ipc reply,鉴别session进程的Oracle进程ID在等什么。要发现这些进程在做什么,你必须找出它们的session。

4.         你所看到的服务器上的后台进程(DBWR,LGWR,PMON等)都是服务进程。要想知道他们在做什么,你必须找到他们的session。

V$PROCESS中的常用列

l         ADDR:进程对象地址

l         PID:oracle进程ID

l         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

 ORDERBY o.object_id, xidusn DESC

3.          

附注:

  在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.EXE

4

5

2492

SYSTEM

ORACLE.EXE

5

6

2496

SYSTEM

ORACLE.EXE

6

7

2508

SYSTEM

ORACLE.EXE

7

8

2520

SYSTEM

ORACLE.EXE

8

9

2524

SYSTEM

ORACLE.EXE

10

12

1316

JSS"junsansi

PlSqlDev.exe

9

13

3420

JSS"junsansi

PlSqlDev.exe

13

14

660

JSS"junsansi

PlSqlDev.exe

还可以通过和 v$bgprocess 连接查询到后台进程的名字:

SELECT s.SID SID, p.spid threadid, p.program processname, bg.NAMENAME

 FROM v$process p, v$session s, v$bgprocess bg

 WHERE p.addr = s.paddr

   AND p.addr = bg.paddr

   AND bg.paddr <> '00';

SID

THREADID

PROCESSNAME

NAME

1

2452

ORACLE.EXE

PMON

2

2460

ORACLE.EXE

DBW0

3

2472

ORACLE.EXE

LGWR

4

2492

ORACLE.EXE

CKPT

5

2496

ORACLE.EXE

SMON

6

2508

ORACLE.EXE

RECO

7

2520

ORACLE.EXE

CJQ0

8

2524

ORACLE.EXE

QMN0

Eygle大师写了一段sql脚本getsql.sql,用来获取指定pid正在执行的sql语句,在此也附注上来。

REM getsql.sql

REM author eygle

REM 在windows上,已知进程ID,得到当前正在执行的语句

REM 在windows上,进程ID为16进制,需要转换,在UNIX直接为10进制

SELECT   /*+ ORDERED */

         sql_text

    FROM v$sqltext a

   WHERE (a.hash_value, a.address) IN (

            SELECT DECODE (sql_hash_value,

                           0, prev_hash_value,

                           sql_hash_value

                          ),

                   DECODE (sql_hash_value, 0, prev_sql_addr, sql_address)

              FROM v$session b

             WHERE b.paddr = (SELECT addr

                                FROM v$process c

                               WHERE c.spid = TO_NUMBER ('&pid', 'xxxx')))

ORDER BY piece ASC

/

 

 

 

 

第八篇--V$LOCK 

  这个视图列出Oracle 服务器当前拥有的锁以及未完成的锁或栓锁请求。如果你觉着session在等待等待事件队列那你应该检查本视图。如果你发现session在等待一个锁。那么按如下先后顺序:

1.         使用V$LOCK找出session持有的锁。

2.         使用V$SESSION找出持有锁或等待锁的session执行的sql语句。

3.         使用V$SESSION_WAIT找出什么原因导致session持有锁堵塞。

4.         使用V$SESSION获取关于持有锁的程序和用户的更多信息。

V$LOCK中的常用列

l         SID:表示持有锁的会话信息。

l         TYPE:表示锁的类型。值包括TM和TX等。

l         LMODE:表示会话等待的锁模式的信息。用数字0-6表示,和表1相对应。

l         REQUEST:表示session请求的锁模式的信息。

l         ID1,ID2:表示锁的对象标识。

公共锁类型

  在Oracle数据库中,DML锁主要包括TM锁和TX锁,其中TM锁称为表级锁,TX锁称为事务锁或行级锁。

  当Oracle执行DML语句时,系统自动在所要操作的表上申请TM类型的锁。当TM锁获得后,系统再自动申请TX类型的锁,并将实际锁定的数据行的锁标志位进行置位。这样在事务加锁前检查TX锁相容性时就不用再逐行检查锁标志,而只需检查TM锁模式的相容性即可,大大提高了系统的效率。TM锁包括了SS、SX、S、X等多种模式,在数据库中用0-6来表示。不同的SQL操作产生不同类型的TM锁,如下表1。

TX:行级锁,事务锁

l         在改变数据时必须是排它模式(mode 6)。

l         每一个活动事务都拥有一个锁。它将在事务结束(commit/rollback)时释放。

l         如果一个块包括的列被改变而没有ITL(interested transaction list)槽位(entries),那么session将锁置于共享模式(mode 4)。当session获得块的ITL槽位时释放。

l         当一个事务首次发起一个DML语句时就获得一个TX锁,该锁保持到事务被提交或回滚。当两个或多个会话在表的同一条记录上执行DML语句时,第一个会话在该条记录上加锁,其他的会话处于等待状态。当第一个会话提交后,TX锁被释放,其他会话才可以加锁。

l         指出回滚段和事务表项

按下列项以避免竞争:

l               避免TX-6类型竞争,需要根据您的应用而定。

l               避免TX-4类型竞争,可以考虑增加对象INITRANS参数值。

TM:表级锁

n         数据库执行任何DDL语句时必须是排它模式;例如,alter table,drop table。

n         执行像insert,update,delete这类DML语句时处于共享模式。它防止其它session对同一个对象同时执行ddl语句。

n         任何对象拥有正被改变的数据,TM锁都将必须存在。

n         锁指向对象。

在TM队列避免竞争,可以考虑屏蔽对象表级锁,屏蔽表级锁防止对象执行任何ddl语句。

ST:空间事务锁

l         每个数据库(非实例)拥有一个ST锁。

l         除了本地管理表空间,在space管理操作(新建或删除extents)时必须是排它模式。

l         对象creation, dropping, extension, 以及truncation都处于这种锁

l         多数公共原因的争夺,是在磁盘排序(并非使用真正的临时表空间)或回滚段扩展或收缩。

按如下项以避免竞争:

l         使用真正的临时表空间(true temporary tablespaces),利用临时文件。临时段在磁盘排序之后并不创建或删除。

l         使用本地管理表空间。

l         指定回滚段避免动态扩展和收缩,或使用自动undo management。

l         避免应用执行创建或删除数据库对象。

UL:用户定义锁

用户可以自定义锁。内容较多并与此节关系不大,略过。

V$LOCK中的连接列

Column                                             View                                Joined Column(s)

SID                                                   V$SESSION                              SID

ID1, ID2, TYPE                         V$LOCK                                   ID1, ID2, TYPE

ID1                                                    DBA_OBJECTS                OBJECT_ID

TRUNCID1/65536)                     V$ROLLNAME                 USN

1.         如果session在等待锁,这可被用于找出session持有的锁,。

2.         可被用于找出DML锁类型的被锁对象(type='TM')

3.         可被用于找出行级事务锁(TYPE='TX')使用中的回滚段,不过,需要通过V$TRANSACTION连接查询得到。

表1 Oracle的TM锁类型

锁模式

锁描述

解释

SQL操作

0

none

 

 

1

NULL

Select

2

SS(Row-S)

行级共享锁,其他对象只能查询这些数据行

Select for update、Lock for update、Lock row share

3

SX(Row-X)

行级排它锁,在提交前不允许做DML操作

Insert、Update、Delete、Lock row share

4

S(Share)

共享锁

Create index、Lock share

5

SSX(S/Row-X)

共享行级排它锁

Lock share row exclusive

6

X(Exclusive)

排它锁

Alter table、Drop able、Drop index、Truncate table 、Lock exclusive

  数字越大锁级别越高, 影响的操作越多。一般的查询语句如select ... from ... ;是小于2的锁, 有时会在v$locked_object出现。select ... from ... for update; 是2的锁。

  当对话使用for update子串打开一个游标时,所有返回集中的数据行都将处于行级(Row-X)独占式锁定,其他对象只能查询这些数据行,不能进行update、delete或select...for 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; --呵呵,等待状态了吧

6.select * from v$lock; --又新增了两条记录,其它一条type=tx,lmode=0

7.查看当前被锁的session正在执行的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

学习动态性能表

第八篇-(2)-V$LOCKED_OBJECT 2007.6.4

  本视图列出系统上的每个事务处理所获得的所有锁。

V$LOCKED_OBJECT中的列说明:

l         XIDUSN:回滚段号

l         XIDSLOT:槽号

l         XIDSQN:序列号

l         OBJECT_ID:被锁对象ID

l         SESSION_ID:持有锁的sessionID

l         ORACLE_USERNAME:持有锁的Oracle 用户名

l         OS_USER_NAME:持有锁的操作系统用户名

l         PROCESS:操作系统进程号

l         LOCKED_MODE:锁模式,值同上表1

示例:

1.以DBA角色, 查看当前数据库里锁的情况可以用如下SQL语句:

select object_id,session_id,locked_mode from v$locked_object;

select t2.username, t2.sid, t2.serial#, t2.logon_time

 from v$locked_object t1, v$session t2

 where t1.session_id = t2.sid orderby t2.logon_time;

如果有长期出现的一列,可能是没有释放的锁。我们可以用下面SQL语句杀掉长期没有释放非正常的锁:

alter system kill session 'sid,serial#';

  评论这张
转发至微博
转发至微博
0   分享到:        
阅读(374)| 评论(0)| 引用 (0) |举报

历史上的今天

相关文章

最近读者

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--相关文章--> <#--历史上的今天--> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2012