了解各类场景下锁、等待事件的特征,有助于快速定位生产问题。

创建测试表

create table testf
(
a varchar(255),
b varchar(255),
c varchar(255),
d varchar(255),
e varchar(255),
f varchar(255),
g varchar(255),
h varchar(255),
i varchar(255),
j varchar(255),
k varchar(255),
l varchar(255),
m varchar(255),
n varchar(255),
o varchar(255),
p varchar(255),
q varchar(255),
r varchar(255),
s varchar(255),
t varchar(255),
u varchar(255),
v varchar(255),
w varchar(255),
x varchar(255),
y varchar(255),
z varchar(255)
);

添加主键约束

alter table testf add constraint pk_a primary key (a);

场景一:
两个session插入同样的值到主键、唯一约束字段中,session1能完成,session2失败报唯一约束失败。

session1
执行insert测试语句

begin
for x in 1..500000 loop
insert into testf values (x,'aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa');
commit;
end loop;
end;
/

查看锁情况

select * from v$lock;
ADDR             KADDR                   SID TY        ID1        ID2      LMODE    REQUEST      CTIME      BLOCK
---------------- ---------------- ---------- -- ---------- ---------- ---------- ---------- ---------- ----------
0700000188A238A8 0700000188A238D0        519 TM     798999          0          3          0         26          0
0700000188ADE520 0700000188ADE558        519 TX     655367   33178285          6          0         26          0

session2
执行insert测试语句

begin
for x in 1..500000 loop
insert into testf values (x,'aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa');
commit;
end loop;
end;
/

查看锁情况

select * from v$lock;
ADDR             KADDR                   SID TY        ID1        ID2      LMODE    REQUEST      CTIME      BLOCK
---------------- ---------------- ---------- -- ---------- ---------- ---------- ---------- ---------- ----------
0700000188A238A8 0700000188A238D0        519 TM     798999          0          3          0         18          0
0700000188A239A8 0700000188A239D0        524 TM     798999          0          3          0          5          0
0700000188ABFF40 0700000188ABFF78        524 TX     589843   30690293          6          0          5          0
0700000188ADEDC0 0700000188ADEDF8        519 TX     393234   23268430          6          0         18          1

block=1出现阻塞线程

查看等待事件v$session_wait

SID USERNAME   MACHINE    EVENT                          P1TEXT             P1 P2TEXT             P2 WAIT_CLASS      P3TEXT             P3 STATE
---------- ---------- ---------- ------------------------------ ---------- ---------- ---------- ---------- --------------- ---------- ---------- -------------------
519 SYS        lpar2      buffer busy waits              file#               1 block#          50800 Concurrency     class#              1 WAITED SHORT TIME
524 SYS        lpar2      enq: TX - row lock contention  name|mode  1415053316 usn<<16 |      393234 Application     sequence     23268430 WAITING
slot
489 SYS        lpar2      SQL*Net message to client      driver id  1650815232 #bytes              1 Network                             0 WAITED SHORT TIME


直到session1完成insert后,session2返回错误:

ERROR at line 1:
ORA-00001: unique constraint (SYS.PKA) violated
ORA-06512: at line 3


场景二:
两个线程插入不同的值到主键、唯一约束字段中,均能完成。
session1
执行测试sql

session 1
begin
for x in 1..500000 loop
insert into testf values (x,'aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa');
commit;
end loop;
end;
/

session2
执行测试sql

begin
for x in 1..500000 loop
insert into testf values (x+500000,'aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaa');
commit;
end loop;
end;
/

未见阻塞进程

select * from v$lock;
ADDR             KADDR                   SID TY        ID1        ID2      LMODE    REQUEST      CTIME      BLOCK
---------------- ---------------- ---------- -- ---------- ---------- ---------- ---------- ---------- ----------
0700000188A238A8 0700000188A238D0        519 TM     798999          0          3          0        103          0
0700000188A239A8 0700000188A239D0        524 TM     798999          0          3          0         86          0
0700000188ABEE00 0700000188ABEE38        524 TX     655395   33173632          6          0         86          0
070000018AB3F708 070000018AB3F740        519 TX     524319   29519550          6          0        103          0

查看等待事件

SID USERNAME   MACHINE    EVENT                          P1TEXT             P1 P2TEXT             P2 WAIT_CLASS      P3TEXT             P3 STATE
---------- ---------- ---------- ------------------------------ ---------- ---------- ---------- ---------- --------------- ---------- ---------- -------------------
519 SYS        lpar2      buffer busy waits              file#               1 block#          66558 Concurrency     class#              1 WAITED SHORT TIME
524 SYS        lpar2      buffer busy waits              file#               1 block#          66562 Concurrency     class#              1 WAITED SHORT TIME
489 SYS        lpar2      SQL*Net message to client      driver id  1650815232 #bytes              1 Network                             0 WAITED SHORT TIME

最终均完成。