Oracle锁的理解

Oracle的锁有很多种类型,除了用户访问常用到的DDL,DML操作引起的锁以外,其实还有其他类型的锁,比如增加表空间(未做深入研究,再如新增extents,做truncation操作,还有临时表空间操作等)等操作。


总的来说,数据库上的锁有两种:

1 排它锁 exclusive locks 即X锁。加上排它锁,其他事务不能读取和修改。

2 共享锁 shared locks 即S锁。加上共享锁,其他事务可以读取但是不能修改。

下面涉及到的其他锁都是以这两种为基础从不同维度衍生出来的。


Oracle锁的五个类别:(很多文章的介绍中只列出前三或者前二)

1 DDL 锁,dictionary lock。字典锁。

2 DML 锁,data lock。数据锁。包括了TM和TX锁。

3 内部锁与闩,Oracle自己管理保护内部数据,通常用户不用关心(或许就类似于上面说到的extents增删,truncation操作等)。

4 Distributed locks 分布式锁,用于OPS(并行服务器中)。

5 PCM locks 并行告诉缓存锁,用于OPS(并行服务器中)。


Oracle锁的三个粒度,这是另一个维度。

1 TX 行级锁,即事务锁,设计到DML操作和commit/rollback操作。

2 TM 锁,表级锁,共五种。

3 数据库级锁,锁定数据库为限制模式alter system enable restricted session,还有startup mount、alter database open read only。这些与DBA密切相关,与一般用户关系不大。


悲观锁和乐观锁:

1 悲观锁:Select ..for update(nowait) 和 Select * from tab1 for update 操作,这种会在表的行上加排它锁,这样其他事务无法读取和修改。

2 乐观锁:数据在select后到update进行并提交的时间段中数据不会修改。这其实有潜在风险,就是select和update中间有其他事务修改了数据。

Oracle建议采用悲观锁,这样更安全。


TM锁类型:(网上查到的资料与我实践的结果不同,这里做了修正)

锁模式锁描述解释SQL操作
0none

1NULLSelect
2RS(Row-S)行级共享锁,其他对象只能查询这些数据行Lock for update 有这种操作?、Lock row share
3RX(Row-X)行级排它锁,在提交前不允许做DML操作Insert、Update、Delete、Select for update、lock row exclusive 
4S(Share)共享锁Create index、Lock share
5SRX(S/Row-X)共享行级排它锁Lock share row exclusive
6X(Exclusive)排它锁Alter table、Drop able、Drop index、Truncate table 、Lock exclusive

对于以上锁,从2到6都是有加锁操作的,下面是具体的例子:

模式锁定的SQL排斥的模式允许的DML
2 RSlock table t in row share mode;6select,insert,update,delete,for update
3 RX

lock table t in row exclusive mode;

select, insert, update, delete, for update(我加的)

4,5,6select,insert,update, delete,for update
4 Slock table t in share mode;3,5,6select
5 SRXlock table t in share row exclusive mode;3,4,5,6select
6 Xlock table t in exclusive mode;2,3,4,5,6select

这其中,模式3可以很好理解,也常见,就是用户插入更新和删除数据时,对表加RX锁,这意味着表上的共享和行上的排它锁,这很容易理解。但是其他模式代表什么意思?不是完全明白。

从另一张图来描述:×表示排斥

-N/ARSRXSSRXX
N/A





RS




×
RX


×××
S

×
××
SRX

××××
X
×××××
SQL语句表锁定模式允许的表锁定模式
select * from ...
RS
RS RX S SRX S
insert into ...RXRS RX
update ...RXRS RX 
delete from ...RXRS RX
select * from for updateRS??? RX???RS RX S SRX ??? RS RX???
lock table in row share modeRSRS RX S SRX
lock table in row exclusive modeRXRS RX
lock table in share modeSRS S
lock table in share row exclusive modeSRXRS
lock table in exclusive modeXRS

这里有个疑问是关于select ... for update的操作,网上的资料显示TM都是RS操作,但是经过我的测试,都是RX操作。是因为数据库版本的问题么?这点不太清楚。


在Oracle中可以通过几个视图来查看锁状态。

v$lock dba_locks v$session v$session_wait v$locked_object

视图名描述说明
v$session查询会话的信息和锁的信息。

sid,serial#:表示会话信息。

program:表示会话的应用程序信息。

row_wait_obj#:表示等待的对象,和dba_objects中的object_id相对应。

v$session_wait查询等待的会话信息。

sid:表示持有锁的会话信息。

Seconds_in_wait:表示等待持续的时间信息

Event:表示会话等待的事件。

v$lock列出系统中的所有的锁。

Sid:表示持有锁的会话信息。

Type:表示锁的类型。值包括TM和TX等。

ID1:表示锁的对象标识。

lmode,request:表示会话等待的锁模式的信息。用数字0-6表示,和表1相对应。

dba_locks对v$lock的格式化视图。

Session_id:和v$lock中的Sid对应。

Lock_type:和v$lock中的type对应。

Lock_ID1: 和v$lock中的ID1对应。

Mode_held,mode_requested:和v$lock中的lmode,request相对应。

v$locked_objects只包含DML的锁信息,包括回滚段和会话信息。

Xidusn,xidslot,xidsqn:表示回滚段信息。和v$transaction相关联。

Object_id:表示被锁对象标识。

Session_id:表示持有锁的会话信息。

Locked_mode:表示会话等待的锁模式的信息,和v$lock中的lmode一致。


这里解释一下v$lock的代表:

列名类型字段说明
ADDRRAW(4|8)Address of lock state object
KADDRRAW(4|8)Address of lock
SIDNUMBER会话的sid,可以和v$session 关联
TYPEVARCHAR2(2)

锁保护对象的类型见上面

TM – DML enqueue

TX – Transaction enqueue

UL – User supplied

更多时候只需要关注TX和TM两种类型的锁

UL锁用户自己定义的,一般很少会定义,很少关注

其它均为系统锁,会很快自动释放,不用关注

ID1NUMBER

ID1,ID2的取值含义根据type的取值而有所不同

对于TM 锁

ID1表示被锁定表的object_id 可以和dba_objects视图关联取得具体表信息,ID2 值为0

对于TX 锁

ID1以十进制数值表示该事务所占用的回滚段号和事务槽slot number号,其组形式:

0xRRRRSSSS,RRRR=RBS/UNDO NUMBER,SSSS=SLOT NUMBER

ID2NUMBERID2 以十进制数值表示环绕wrap的次数,即事务槽被重用的次数
LMODENUMBER

0、无

1、NULL,可以某些情况下,如分布式数据库的查询会产生此锁。

2、SS,表结构共享锁

3、SX,表结构共享锁+被操作的记录的排它锁

4、S, 表结构共享锁+所有记录共享锁

5、SRX 表结构共享锁+所有记录排它锁

6、X   表结构排它锁+所有记录排它锁

以下为补充上面 摘自:http://www.itpub.net/thread-940126-1-1.html 

    2   SS, 表结构共享+加上部分数据共享.虽然有人说,ORACLE里,数据没有S状态,但我还是愿意这样理解:

         第1个S代表表结构共享.

         第2个代表表里的数据共享. 

         你可以想象一下,当往子表里增加纪录时,主表的相关主键是不是得处于共享模式.

    3    SX,   用于DML操作,第1个S代表表结构共享,第2个代表表里被操作的数据独占.

    4    S, 代表表结构+表里的数据都是处于共享模式.当对表创建索引时,在创建期间,表处于这种模式.

    5    SRX=S(4)+SX(3), 

    6    X, 删除表是会用上.

REQUEST
NUMBER

同上LMODE

大于0时,表示当前会话被阻塞,其它会话占有改锁的模式

CTIMENUMBER已持有或者等待锁的时间
BLOCKNUMBER是否阻塞其他会话锁申请 2:Global  1:阻塞  0:不阻塞

下面是具体详细的说明:

ADDR  

Address of lock state object 


KADDR  

Address of lock 


Lock Type  

System Type  

BL Buffer hash table instance 

CF Control file schema global enqueue 

CI Cross-instance function invocation instance 

CU Cursor bind 

DF Data file instance 

DL Direct loader parallel index create 

DM Mount/startup db primary/secondary instance 

DR Distributed recovery process 

DX Distributed transaction entry 

FS File set 

HW Space management operations on a specific segment 

IN Instance number 

IR Instance recovery serialization global enqueue 

IS Instance state 

IV Library cache invalidation instance 

JQ Job queue 

KK Thread kick 

LA .. LP Library cache lock instance lock (A..P = namespace) 

MM Mount definition global enqueue 

MR Media recovery 

NA..NZ Library cache pin instance (A..Z = namespace) 

PF Password File 

PI, PS Parallel operation 

PR Process startup 

QA..QZ Row cache instance (A..Z = cache) 

RT Redo thread global enqueue 

SC System change number instance 

SM SMON 

SN Sequence number instance 

SQ Sequence number enqueue 

SS Sort segment 

ST Space transaction enqueue 

SV Sequence number value 

TA Generic enqueue 

TS Temporary segment enqueue (ID2=0) 

TS New block allocation enqueue (ID2=1) 

TT Temporary table enqueue 

UN User name 

US Undo segment DDL 

WL Being-written redo log instance 


User Type  

TX --- Transaction 

TM --- Table Manipulate 

UL --- PL/SQL USER LOCK 


lmode(Lock mode)  

Lock mode in which the session holds the lock: 

- none 

- null (NULL) 

- row-S (SS) 

- row-X (SX) 

- share (S) 

- S/Row-X (SSX) 

- exclusive (X) 


request  

Lock mode in which the process requests the lock: 

- none 

- null (NULL) 

- row-S (SS) 

- row-X (SX) 

- share (S) 

- S/Row-X (SSX) 

- exclusive (X) 


Block  

--- Not blocking any other processes 

--- This lock blocks other processes 

--- Global


在数据库中验证:

执行lock table <table name> in row share mode,然后在v$lock中可以看到有一条记录TM锁,LMODE值为2。同时有条TX记录,LMODE为6。这里的LMODE就代表了TM锁模式,RS RX S 等等。

block字段代表了是否有其他事务等待这个锁。


下面是查询锁的一些有用的SQL:

select * from v$session where sid in ( select sid from v$lock where block=1 or request=6);

select sid,serial#,sql_id,prev_sql_id,ROW_WAIT_OBJ#,ROW_WAIT_FILE#,ROW_WAIT_BLOCK#,ROW_WAIT_ROW# from v$session where sid in ( select sid from v$lock where block=1 or request=6);

select s.sid,s.SERIAL#,s.STATUS,s.MACHINE,s.username,s.OSUSER,s.BLOCKING_SESSION,s.SQL_ID,s.PREV_SQL_ID,s.BLOCKING_INSTANCE,s.BLOCKING_SESSION_STATUS 
from v$session s
where s.BLOCKING_SESSION>0;

select s.sid,s.SERIAL#,s.STATUS,s.MACHINE,s.username,s.OSUSER,s.BLOCKING_SESSION,s.SQL_ID,s.PREV_SQL_ID,s.LOGON_TIME,s.BLOCKING_INSTANCE,s.BLOCKING_SESSION_STATUS  
from v$session s where sid in ( select sid from v$lock where block=1 or request=6);

select s.sid,s.SERIAL#,s.STATUS,s.MACHINE,s.username,s.OSUSER,s.BLOCKING_SESSION,s.SQL_ID,s.PREV_SQL_ID,s.LOGON_TIME,s.BLOCKING_INSTANCE,s.BLOCKING_SESSION_STATUS 
from v$session s
where s.BLOCKING_SESSION>0;

select sid,sql_id,prev_sql_id,
'select object_name from dba_objects where object_id='||ROW_WAIT_OBJ#||';',
'select dbms_rowid.rowid_create(1,'||ROW_WAIT_OBJ#||','||ROW_WAIT_FILE#||','||ROW_WAIT_BLOCK#||','||ROW_WAIT_ROW# ||') from dual;'
from v$session where sid in ( select sid from v$lock where block=1 or request=6)
order by sql_id;


死锁:

死锁是两个会话互相请求对方已锁定资源引起互相等待,oracle中会自动杀掉其中一个会话(什么样的选择机制?)。

转载于:https://my.oschina.net/shawnplaying/blog/615734

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值