记录一个很诡异的问题,在进行一个测试时碰到的,V$SESSION中记录的BLOCKING_SESSION信息是错误的,可惜这个问题当时没有注意,后续也无法再重现出来,只好作为一个现象记录一下,Oracle给出的一些信息看来也是不完全可信的。
在会话1执行:
[tingkun.yang@node1 ~]$ sqlplus test/test SQL*Plus: Release 10.2.0.5.0 - Production ON Sun Nov 25 04:04:00 2012 Copyright (c) 1982, 2010, Oracle. ALL Rights Reserved. Connected TO: Oracle DATABASE 10g Enterprise Edition Release 10.2.0.5.0 - 64bit Production WITH the Partitioning, REAL Application Clusters, OLAP, DATA Mining AND REAL Application Testing options SQL> SET pages 100 LINES 140 SQL> CREATE TABLE t_lock (id NUMBER, name varchar2(30), gender varchar2(8)); TABLE created. SQL> INSERT INTO t_lock VALUES (1, 'a', 'm'); 1 ROW created. SQL> INSERT INTO t_lock VALUES (2, 'b', 'f'); 1 ROW created. SQL> commit; Commit complete. SQL> UPDATE t_lock SET name = 'c' WHERE id = 1; 1 ROW updated. SQL> SELECT sid FROM v$mystat WHERE rownum = 1; SID ---------- 151 |
在会话2执行同一行的更新,被锁定:
[tingkun.yang@node1 ~]$ sqlplus test/test SQL*Plus: Release 10.2.0.5.0 - Production ON Sun Nov 25 04:03:27 2012 Copyright (c) 1982, 2010, Oracle. ALL Rights Reserved. Connected TO: Oracle DATABASE 10g Enterprise Edition Release 10.2.0.5.0 - 64bit Production WITH the Partitioning, REAL Application Clusters, OLAP, DATA Mining AND REAL Application Testing options SQL> SET pages 100 LINES 120 SQL> UPDATE t_lock SET name = 'd' WHERE id = 1; |
在会话3上执行对V$SESSION的查询,当时没有太注意:
SQL> conn / AS sysdba Connected. SQL> SELECT sid, event, blocking_session FROM v$session WHERE usernamE = 'TEST'; SID EVENT BLOCKING_SESSION ---------- ---------------------------------------------------------------- ---------------- 131 SQL*Net message FROM client 151 SQL*Net message FROM client SQL> SELECT sid, event, blocking_session FROM v$session WHERE usernamE = 'TEST'; SID EVENT BLOCKING_SESSION ---------- ---------------------------------------------------------------- ---------------- 131 enq: TX - ROW LOCK contention 161 151 SQL*Net message FROM client |
随后在会话1执行了ROLLBACK:
SQL> roll; ROLLBACK complete. |
检查了会话2的连接信息:
1 ROW updated. SQL> SELECT sid FROM v$mystat WHERE rownum = 1; SID ---------- 131 |
这时才发现,之前查询的V$SESSION中的BLOCKING_SESSION信息是错误的。当前数据库只有两个测试会话,分别是131和151,而BLOCKING_SESSION给出的结果居然是161。虽然V$SESSION中还有BLOCKING_SESSION_STATUS列来表示当前的BLOCKING_SESSION是否有意义,但是一般而言,如果BLOCKING_SESSION_STATUS的值不是VALID,那么BLOCKING_SESSION的值会是NULL,但是像这种值本身就是错误的,还是第一次碰到。
由于没有办法重现,现在确定不了Oracle为什么会出现这种问题,只能先作为一个异常案例记录一下,如果以后发现类似的错误,再进行分析。不过这提示一点,Oracle视图的返回结果经常作为我们诊断、分析问题的依据,但是如果结果本身不可信,那么在此基础上推导出来的结果很可能也是不可信的。