<<Oracle数据库性能优化艺术(第五期)>> 第2周 锁

1.分别模拟insert,update和delete造成阻塞的示例,并对v$lock中的相应的信息进行说明,给出SQL演示。

1.1 insert:

SQL> select distinct sid from v$mystat;

       SID
----------
       373

SQL> drop table t;

Table dropped.

SQL> create table t (id int primary key);

Table created.

SQL> insert into t values(1);

1 row created.

SQL>

======================================

SQL> select distinct sid from v$mystat;

       SID
----------
       272

SQL> select * from t;

no rows selected

SQL> insert into t values(1);

--session272在这里卡住

======================================

v$lock信息:

SQL> select * from v$lock where sid in (373,272) order by sid desc;

ADDR             KADDR                   SID TY        ID1        ID2      LMODE    REQUEST      CTIME      BLOCK
---------------- ---------------- ---------- -- ---------- ---------- ---------- ---------- ---------- ----------
00000000DBD6BBC0 00000000DBD6BC38        373 TX     327694    3198697          6          0        133          1
00000000DD1A7DE0 00000000DD1A7E38        373 AE    3269431          0          4          0        909          0
00007FA8635EC088 00007FA8635EC0E8        373 TM    3321815          0          3          0        133          0
00000000DD1A9178 00000000DD1A91D0        373 TO    3290249          1          3          0        881          0
00007FA8635EC088 00007FA8635EC0E8        272 TM    3321815          0          3          0        106          0
00000000DBDB30F8 00000000DBDB3170        272 TX     458754    2502943          6          0        106          0
00000000DD1AA798 00000000DD1AA7F0        272 AE    3269431          0          4          0        264          0
00000000DD1AAD48 00000000DD1AADA0        272 TX     327694    3198697          0          4        106          0

8 rows selected.

SQL>



1.2 update:


SQL> select * from t;

        ID
----------
         1

SQL> select distinct sid from v$mystat;

       SID
----------
       209

SQL> select * from t;

        ID
----------
         1

SQL> update t set id=2 where id=1;

1 row updated.

SQL>

======================================

SQL> select distinct sid from v$mystat;

       SID
----------
       202

SQL> update t set id=3 where id=1;

--session202卡住

======================================


v$lock信息:


SQL> select * from v$lock where sid in (209,202) order by sid desc;

ADDR             KADDR                   SID TY        ID1        ID2      LMODE    REQUEST      CTIME      BLOCK
---------------- ---------------- ---------- -- ---------- ---------- ---------- ---------- ---------- ----------
00000000DD1A7DE0 00000000DD1A7E38        209 AE    3269431          0          4          0        200          0
00007F0617F77AE0 00007F0617F77B40        209 TM    3321815          0          3          0         85          0
00000000DBD20C68 00000000DBD20CE0        209 TX     327696    3198961          6          0         85          1
00007F0617F77AE0 00007F0617F77B40        202 TM    3321815          0          3          0         70          0
00000000DD1A9178 00000000DD1A91D0        202 AE    3269431          0          4          0        194          0
00000000DD1AA798 00000000DD1AA7F0        202 TX     327696    3198961          0          6         70          0

6 rows selected.

SQL>



1.3 delete:


SQL> select distinct sid from v$mystat;

       SID
----------
       209

SQL> select * from t;

        ID
----------
         1

SQL> delete from t where id=1;

1 row deleted.

SQL>

======================================

SQL> select distinct sid from v$mystat;

       SID
----------
       202

SQL> delete from t where id=1;
--session 202 卡住
======================================


v$lock信息:


SQL> select * from v$lock where sid in (209,202) order by sid desc;

ADDR             KADDR                   SID TY        ID1        ID2      LMODE    REQUEST      CTIME      BLOCK
---------------- ---------------- ---------- -- ---------- ---------- ---------- ---------- ---------- ----------
00000000DD1A7DE0 00000000DD1A7E38        209 AE    3269431          0          4          0        438          0
00007F0617F76AA8 00007F0617F76B08        209 TM    3321815          0          3          0         66          0
00000000DBD20C68 00000000DBD20CE0        209 TX     196626    3278256          6          0         66          1
00007F0617F76AA8 00007F0617F76B08        202 TM    3321815          0          3          0         56          0
00000000DD1A9178 00000000DD1A91D0        202 AE    3269431          0          4          0        432          0
00000000DD1AA798 00000000DD1AA7F0        202 TX     196626    3278256          0          6         56          0

6 rows selected.

SQL>


--EOF--


2.模拟RI锁定导致阻塞的场景,并分析v$lock相应的锁定信息,给出SQL演示。

=============================================

测试主表增删改:

SQL> create table p(id int primary key);

Table created.

SQL> create table c(id references p(id));

Table created.

SQL> insert into p values(1);

1 row created.

SQL> insert into p values(2);

1 row created.

SQL> insert into c values(1);

1 row created.

SQL> commit;

Commit complete.

SQL> insert into c values(3);
insert into c values(3)
*
ERROR at line 1:
ORA-02291: integrity constraint (SYSTEM.SYS_C0013952) violated - parent key not
found


SQL> insert into p values(3);

1 row created.

SQL> select distinct sid from v$mystat;

       SID
----------
    34

SQL> set linesize 200
SQL> select * from v$lock where sid in (34);

ADDR         KADDR             SID TY        ID1      ID2       LMODE    REQUEST     CTIME        BLOCK
---------------- ---------------- ---------- -- ---------- ---------- ---------- ---------- ---------- ----------
00000000718597E8 0000000071859840      34 AE        100        0           4      0       150        0
000000007185A290 000000007185A2E8      34 TO      65927        1           3      0       132        0
00007F799CA040B8 00007F799CA04118      34 TM      77329        0           3      0        42        0
00007F799CA040B8 00007F799CA04118      34 TM      77331        0           3      0        42        0

0000000070AC9830 0000000070AC98A8      34 TX     131076     1103           6      0        42        0

SQL> rollback;

Rollback complete.

SQL> update p set id=3 where id=1;
update p set id=3 where id=1
*
ERROR at line 1:
ORA-02292: integrity constraint (SYSTEM.SYS_C0013952) violated - child record found


SQL> update p set id=3 where id=2;

1 row updated.

SQL> select * from v$lock where sid in (34);

ADDR         KADDR             SID TY        ID1      ID2       LMODE    REQUEST     CTIME        BLOCK
---------------- ---------------- ---------- -- ---------- ---------- ---------- ---------- ---------- ----------
00000000718597E8 0000000071859840      34 AE        100        0           4      0       200        0
000000007185A290 000000007185A2E8      34 TO      65927        1           3      0       182        0
00007F799C61C260 00007F799C61C2C0      34 TM      77329        0           3      0         4        0
0000000070AC9830 0000000070AC98A8      34 TX     262161      825           6      0         4        0

SQL> rollback;

Rollback complete.

SQL> delete from p where id=2;

1 row deleted.

SQL> select * from v$lock where sid in (34);

ADDR         KADDR             SID TY        ID1      ID2       LMODE    REQUEST     CTIME        BLOCK
---------------- ---------------- ---------- -- ---------- ---------- ---------- ---------- ---------- ----------
00000000718597E8 0000000071859840      34 AE        100        0           4      0       221        0
000000007185A290 000000007185A2E8      34 TO      65927        1           3      0       203        0
00007F799C61C260 00007F799C61C2C0      34 TM      77329        0           3      0         2        0
0000000070AC9830 0000000070AC98A8      34 TX     458773      903           6      0         2        0

SQL> rollback;

Rollback complete.
=============================================

测试从表增删改:

SQL> insert into c values(2);

1 row created.

SQL> select * from v$lock where sid in (34);

ADDR         KADDR             SID TY        ID1      ID2       LMODE    REQUEST     CTIME        BLOCK
---------------- ---------------- ---------- -- ---------- ---------- ---------- ---------- ---------- ----------
00000000718597E8 0000000071859840      34 AE        100        0           4      0       237        0
000000007185A290 000000007185A2E8      34 TO      65927        1           3      0       219        0
00007F799C61C260 00007F799C61C2C0      34 TM      77329        0           3      0         3        0
00007F799C61C260 00007F799C61C2C0      34 TM      77331        0           3      0         3        0

0000000070AC9830 0000000070AC98A8      34 TX     393240     1124           6      0         3        0

SQL> rollback;

Rollback complete.

SQL> update c set id=2 where id=1;

1 row updated.

SQL> select * from v$lock where sid in (34);

ADDR         KADDR             SID TY        ID1      ID2       LMODE    REQUEST     CTIME        BLOCK
---------------- ---------------- ---------- -- ---------- ---------- ---------- ---------- ---------- ----------
00000000718597E8 0000000071859840      34 AE        100        0           4      0       261        0
000000007185A290 000000007185A2E8      34 TO      65927        1           3      0       243        0
00007F799C61C260 00007F799C61C2C0      34 TM      77329        0           3      0         2        0
00007F799C61C260 00007F799C61C2C0      34 TM      77331        0           3      0         2        0

0000000070AC9830 0000000070AC98A8      34 TX     327706     1270           6      0         2        0

SQL> rollback;

Rollback complete.

SQL> delete from c where id=1;

1 row deleted.

SQL> select * from v$lock where sid in (34);

ADDR         KADDR             SID TY        ID1      ID2       LMODE    REQUEST     CTIME        BLOCK
---------------- ---------------- ---------- -- ---------- ---------- ---------- ---------- ---------- ----------
00000000718597E8 0000000071859840      34 AE        100        0           4      0       275        0
000000007185A290 000000007185A2E8      34 TO      65927        1           3      0       257        0
00007F799C61C260 00007F799C61C2C0      34 TM      77329        0           3      0         2        0
00007F799C61C260 00007F799C61C2C0      34 TM      77331        0           3      0         2        0

0000000070AC9830 0000000070AC98A8      34 TX     589856     1104           6      0         2        0

SQL> rollback;

Rollback complete.

SQL> 


可见,在主表上操作时,只有insert才会在从表上加一个row exclusive(3)锁;

而在从表上操作时,无论insert/update/delete都会在主表上加一个row exclusive(3)锁.


--EOF--


3.自己构想一个使用手工锁定解决一种业务需求的场景,并给出SQL演示。

模拟订票流程,手工锁定已查询出来的票

SQL> drop table tickets purge;

Table dropped.

SQL> create table tickets(id int primary key, price int);

Table created.

SQL> insert into tickets values(1,100);

1 row created.

SQL> insert into tickets values(2,200);

1 row created.

SQL> commit;

Commit complete.

SQL> select * from tickets where id=1 for update;

        ID      PRICE
---------- ----------
         1        100

SQL>

=======================================

SQL> select * from tickets where id=1;

        ID      PRICE
---------- ----------
         1        100

SQL> select * from tickets where id=1 for update nowait;
select * from tickets where id=1 for update nowait
              *
ERROR at line 1:
ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired


SQL>


--EOF--


4.给出从mode 2-6 的TM锁相互间的互斥示例。

session=209,LMODE=2

SQL> select distinct sid from v$mystat;

       SID
----------
       209

SQL> lock table t in row share mode;

Table(s) Locked.

SQL>

=======================================

session=373,LMODE=3

SQL> select distinct sid from v$mystat;

       SID
----------
       373

SQL> lock table t in row exclusive mode;

Table(s) Locked.

SQL>

=======================================

session=272,LMODE=4

SQL> select distinct sid from v$mystat;

       SID
----------
       272

SQL> lock table t in share mode;
--卡住

=======================================

session=231,LMODE=5

SQL> select distinct sid from v$mystat;

       SID
----------
       231

SQL> lock table t in share row exclusive mode;
--卡住

=======================================

session=202,LMODE=6

SQL> select distinct sid from v$mystat;

       SID
----------
       202

SQL> lock table t in exclusive mode;
--卡住
=======================================

查询v$lock发现row share(2)/row exclusive(3)阻塞了share(4)/share row exclusive(5)/exclusive(6)

SQL> select sid,type,id1,id2,lmode,request,block from v$lock where sid in (209,373,272,231,202) and type = 'TM';

       SID TY        ID1        ID2      LMODE    REQUEST      BLOCK
---------- -- ---------- ---------- ---------- ---------- ----------
       209 TM    3321898          0          2          0          1
       373 TM    3321898          0          3          0          1
       272 TM    3321898          0          0          4          0
       231 TM    3321898          0          0          5          0
       202 TM    3321898          0          0          6          0

SQL>



参考资料:

Automatic Locks in DML Operations
http://docs.oracle.com/cd/E11882_01/server.112/e41084/ap_locks001.htm


lockmode Clause

Specify one of the following modes:

ROW SHARE  ROW SHARE permits concurrent access to the locked table but prohibits users from locking the entire table for exclusive access. ROW SHARE is synonymous with SHARE UPDATE, which is included for compatibility with earlier versions of Oracle Database.

ROW EXCLUSIVE  ROW EXCLUSIVE is the same as ROW SHARE, but it also prohibits locking in SHARE mode. ROW EXCLUSIVE locks are automatically obtained when updating, inserting, or deleting.

SHARE UPDATE  See ROW SHARE.

SHARE SHARE permits concurrent queries but prohibits updates to the locked table.

SHARE ROW EXCLUSIVE  SHARE ROW EXCLUSIVE is used to look at a whole table and to allow others to look at rows in the table but to prohibit others from locking the table in SHARE mode or from updating rows.

EXCLUSIVE  EXCLUSIVE permits queries on the locked table but prohibits any other activity on it.


http://docs.oracle.com/cd/B19306_01/server.102/b14200/statements_9015.htm


--EOF--


5.给出一个导致死锁的SQL示例。

session1:

SQL> select * from t;

        ID
----------
         1
         2

SQL> update t set id=10 where id=1;

1 row updated.
=======================================
session2:

SQL> update t set id=20 where id=2;

1 row updated.
=======================================
session1:

SQL> update t set id=10 where id=2;

--卡住
=======================================
session2:

SQL> update t set id=20 where id=1;

--卡住

=======================================
session1报死锁错:

SQL> update t set id=10 where id=2;
update t set id=10 where id=2
       *
ERROR at line 1:
ORA-00060: deadlock detected while waiting for resource


SQL>

=======================================
session2:SQL> update t set id=20 where id=1;

--继续卡住



--EOF--

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值