了解各类场景下锁、等待事件的特征,有助于快速定位生产问题。
创建测试表
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
最终均完成。