[20180222]V$LOCK视图显示大量TX锁.txt

[20180222]V$LOCK视图显示大量TX锁.txt

--//一般应用程序许多情况下一个TX锁,对应一个TM锁(一般DML都是单表,然后提交).生产系统存在大量的有TX锁,而没有TM锁.
--//实际上很容易发现问题在于应用存在大量的通过dblink访问的情况,通过例子说明:

1.环境:
SCOTT@book> @ ver1
PORT_STRING                    VERSION        BANNER
------------------------------ -------------- --------------------------------------------------------------------------------
x86_64/Linux 2.4.xx            11.2.0.4.0     Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production

CREATE PUBLIC DATABASE LINK LOOPBACK
CONNECT TO SCOTT
IDENTIFIED BY <PWD>
USING 'localhost:1521/book:DEDICATED';

2.测试一:
SCOTT@book> create table empx as select * from emp;
Table created.

SCOTT@book> @ &r/spid

       SID    SERIAL# PROCESS                  SERVER    SPID       PID  P_SERIAL# C50
---------- ---------- ------------------------ --------- ------ ------- ---------- --------------------------------------------------
       274         97 38697                    DEDICATED 38698       21         47 alter system kill session '274,97' immediate;

SCOTT@book> @ &r/xid
XIDUSN_XIDSLOT_XIDSQN
------------------------------

no rows selected

SCOTT@book> select * from empx@loopback ;

SCOTT@book> @ &r/xid
XIDUSN_XIDSLOT_XIDSQN
------------------------------
10.15.22681

SCOTT@book> select * from v$lock where sid =(select distinct sid from v$mystat) and type in ('TX','TM');
ADDR             KADDR                   SID TYPE        ID1        ID2      LMODE    REQUEST      CTIME      BLOCK
---------------- ---------------- ---------- ---- ---------- ---------- ---------- ---------- ---------- ----------
0000000081BE6218 0000000081BE6290        274 TX       655375      22681          6          0         22          0

--//你可以发现当前会话仅仅存在tx锁.id1前16位,后16位分别表示事务的XIDUSN,XIDSLOT.id2表示XIDSQN.
SCOTT@book> @ &r/tx1 655375 16
select 655375,trunc(655375/power(2,16)) XIDUSN,mod(655375,power(2,16))  XIDSLOT from dual
    655375     XIDUSN    XIDSLOT
---------- ---------- ----------
    655375         10         15

--//可以发现如果大量的dblink访问就会出现这样的情况.如果通过dblink执行dml语句,这样另外的数据库就存在大量TM,TX锁.继续测试:

SCOTT@book> commit ;
Commit complete.

SCOTT@book> @ &r/xid
XIDUSN_XIDSLOT_XIDSQN
------------------------------

no rows selected

SCOTT@book> create table t (a int);
Table created.

SCOTT@book> select data_object_id,object_id from dba_objects where object_name='T' and owner=user;
DATA_OBJECT_ID  OBJECT_ID
-------------- ----------
         92614      92614

SCOTT@book> insert into t@loopback values (1);
1 row created.

SCOTT@book> @ &r/xid
XIDUSN_XIDSLOT_XIDSQN
------------------------------
10.5.22687

SCOTT@book> select * from v$lock where sid =(select distinct sid from v$mystat) and type in ('TX','TM');
ADDR             KADDR               SID TYPE        ID1        ID2      LMODE    REQUEST      CTIME    BLOCK
---------------- ---------------- ------ ---- ---------- ---------- ---------- ---------- ---------- --------
0000000081BE6218 0000000081BE6290    274 TX       655365      22687          6          0         40        0

SCOTT@book> select * from v$lock where id1= 92614;
ADDR             KADDR               SID TYPE   ID1        ID2      LMODE    REQUEST      CTIME      BLOCK
---------------- ---------------- ------ ---- ------ ---------- ---------- ---------- --------- ----------
00007F4DC6FE3D68 00007F4DC6FE3DC8     80 TM   92614          0          3          0        153          0

SCOTT@book> @ &r/viewlock
   SID    SERIAL# USERNAME   OSUSER     MACHINE    MODULE       LOCK_TYPE       MODE_HELD  MODE_REQUE LOCK_ID1   LOCK_ID2   OWNER  OBJECT_TYP OBJECT_NAME BLOCK LOCKWAIT
------ ---------- ---------- ---------- ---------- ------------ --------------- ---------- ---------- ---------- ---------- ------ ---------- ----------- ----- ---------
    80        181 SCOTT      oracle     gxqyydg4   oracle@gxqyy TM DML(TM)      Row-X (SX) None       92614      0          SCOTT  TABLE      T           No
   274         97 SCOTT      oracle     gxqyydg4   SQL*Plus     TX Transaction  Exclusive  None       655365     22687                                    No

--//因为我的测试在单机环境模拟dblink,出现TM锁也在这台服务器.

3.测试二:

--//还有什么情况会出现这样情况呢?设置表属性disable table lock,这样就没有TM锁存在,一般应用很少这样的情况.

SCOTT@book> alter table t disable table lock;
Table altered.

SCOTT@book> insert into t values(2);
1 row created.

SCOTT@book> @ &r/xid
XIDUSN_XIDSLOT_XIDSQN
------------------------------
10.32.22661

SCOTT@book> select * from v$lock where sid =(select distinct sid from v$mystat) and type in ('TX','TM');
ADDR             KADDR               SID TYPE        ID1        ID2      LMODE    REQUEST      CTIME    BLOCK
---------------- ---------------- ------ ---- ---------- ---------- ---------- ---------- ---------- --------
0000000081BE6218 0000000081BE6290    274 TX       655392      22661          6          0         23        0

--//注意这样的表不能删除,truncate,增加修改字段类型等操作.
SCOTT@book> truncate table t ;
truncate table t
               *
ERROR at line 1:
ORA-00069: cannot acquire lock -- table locks disabled for T

SCOTT@book> drop table t ;
drop table t
           *
ERROR at line 1:
ORA-00069: cannot acquire lock -- table locks disabled for T

4.测试3:
--//在事务中使用savepoint也会出现,因为执行这个命令就在之前建立事务.
SCOTT@book> @ &r/xid
XIDUSN_XIDSLOT_XIDSQN
------------------------------

no rows selected

SCOTT@book> savepoint a;
Savepoint created.

SCOTT@book> @ &r/xid
XIDUSN_XIDSLOT_XIDSQN
------------------------------
10.13.22684


SCOTT@book> select * from v$lock where sid =(select distinct sid from v$mystat) and type in ('TX','TM');
ADDR             KADDR               SID TYPE        ID1        ID2      LMODE    REQUEST      CTIME    BLOCK
---------------- ---------------- ------ ---- ---------- ---------- ---------- ---------- ---------- --------
0000000081B361C8 0000000081B36240    274 TX       655373      22684          6          0         14        0

--//这样就仅仅存在tx锁,而没有TM锁.注意如果回滚到a,事务依旧存在.

SCOTT@book> rollback to a;
Rollback complete.

SCOTT@book> @ &r/xid
XIDUSN_XIDSLOT_XIDSQN
------------------------------
10.13.22684

SCOTT@book> select * from v$lock where sid =(select distinct sid from v$mystat) and type in ('TX','TM');
ADDR             KADDR               SID TYPE        ID1        ID2      LMODE    REQUEST      CTIME    BLOCK
---------------- ---------------- ------ ---- ---------- ---------- ---------- ---------- ---------- --------
0000000081B361C8 0000000081B36240    274 TX       655373      22684          6          0        158        0

SCOTT@book> commit ;
Commit complete.

SCOTT@book> select * from v$lock where sid =(select distinct sid from v$mystat) and type in ('TX','TM');
no rows selected

--//还有那种情况会出现这样的情况,我就不知道了...也许还存在许多可能,我想到就这些.

4.总结:
--//dblink
--//表disable table lock;
--//建立savepoint.

上一篇:自定义Dialog之旅程(二)理解Dialog大小


下一篇:自定义Dialog之旅程(三)Dialog动画