lock 锁.docx
- 文档编号:10292049
- 上传时间:2023-02-09
- 格式:DOCX
- 页数:19
- 大小:23.03KB
lock 锁.docx
《lock 锁.docx》由会员分享,可在线阅读,更多相关《lock 锁.docx(19页珍藏版)》请在冰豆网上搜索。
lock锁
lock锁
1锁的作用和分类
1.1锁的作用
锁为了避免资源竞争控制并发
说白了就是保护自己+限制别人
1.2锁的基本分类
按照锁级别:
TM表(共享)TX行(排他)
按操作划分:
DML锁updatetablet1共享DDL锁altertablet1
规定类型模式0-67
内部闩锁:
这是ORACLE中的一种特殊锁,用于顺序访问内部系统结构。
当事务需向缓冲区写入信息时,为了使用此块内存区域,ORACLE首先必须取得这块内存区域的闩锁,才能向此块内存写入信息。
1.3锁的基本说明
记住:
在oracle里select不产生查询保护锁(除了select..forupdate;本节介绍)
LATCH涉及不可见的内部对象比如librarycache
LATCH暂时不讲今天只认识DML和DDL锁
锁的触发
用户执行的DMLDDL操作间接触发
用户执行的locktable.....语句直接触发
DML锁
也就是INSERT,UPDATE,DELETE,selectFORUPDATE操作产生的锁
DML执行就会产生事务所以锁和事务是分不开的
DML锁目的就用来控制多个session(不一定是多个用户)并行访问的数据时一致性的.
确保在某一事务期间修改的数据,不能被另一个用户修改和编辑
DML锁也确保了被修改中的表(事务未结束)不能做DDL
DML锁的两种类型
DML针对的对象通常是表
表又分为行和列数据存储是以行记录模式存储在块里的DML就是操作表中的行
所以DML锁分为:
表级锁TM(tablemanagement)
行级锁TX(transactionexclusive)
锁的信息可以通过如下性能视图查得
v$lock
v$locked_object
dba_blockers
dba_waiters
dba_dml_locks
dba_ddl_locks
1.4测试
实验认识TM,TX锁和阻塞
认识外键有索引的必要性
启用三个会话
sessionAsessionB互动操作产生现象
sessionC查看锁资源
SQL>connscott/seker
Connected.
SQL>setsqlp'sessionA:
>'
sessionA:
>
sessionA:
>selectdistinctsidfromv$mystat;
SID
----------
151
sessionA:
>
SQL>connscott/seker
Connected.
SQL>setsqlp'sessionB:
>'
sessionB:
>
sessionB:
>selectdistinctsidfromv$mystat;
SID
----------
146
sessionB:
>
SQL>connscott/seker
Connected.
SQL>setsqlp'LOOKC:
>'
LOOKC:
>
先查看AB没有操作没有锁产生
LOOKC:
>select*fromv$lockwheresidin(143,159);
norowsselected
LOOKC:
>
操作
sessionA:
>deleteempwhereename='SCOTT';
1rowdeleted.
sessionA:
>
查看
LOOKC:
>select*fromv$lockwheresidin(151,146);
ADDRKADDRSIDTYID1ID2LMODEREQUESTCTIMEBLOCK
----------------------------------------------------------------------------------------
2F9C3F902F9C3FA8151TM5114602090
2F9C403C2F9C4054151TM5114803090
2FA259482FA25A64151TX6553733076090
LOOKC:
>
LOOKC:
>selectOBJECT_NAME,OBJECT_IDfromuser_objectswhereOBJECT_IDin(52506,52508);
OBJECT_NAMEOBJECT_ID
------------------------------
DEPT51146
EMP51148
LOOKC:
>
A操作的是emp中的一行,所以会有TX锁SCOTT这一行
另外两个TM呢?
分别在EMP和dept上DEPT为什么有表锁?
因为他们有主外键约束关系
从外键删除数据,主键表会被锁,我再调配这个部门的员工你不能此时把这个部门删掉.
sessionB:
>deleteempwhereename='SCOTT';
被阻塞
因为这一行被A锁住了B的操作遭到了A的排斥
LOOKC:
>select*fromv$lockwheresidin(159,143);
ADDRKADDRSIDTYID1ID2LMODEREQUESTCTIMEBLOCK
----------------------------------------------------------------------------------------
30FB9B4430FB9B58146TX19664737006340
2F9C3F902F9C3FA8151TM511460202440
2F9C403C2F9C4054151TM511480302440
2F9C40E82F9C4100146TM51146020340
2F9C41942F9C41AC146TM51148030340
2FA259482FA25A64151TX196647370602441
6rowsselected.
LOOKC:
>
A的TX锁阻塞了另一个会话从BLOCK1能看出
获取阻塞信息
select
(selectusernamefromv$sessionwheresid=a.sid)blocker,
a.sid,
'isblocking',
(selectusernamefromv$sessionwheresid=b.sid)blockee,
b.sid
fromv$locka,v$lockb
wherea.block=1
andb.request>0
anda.id1=b.id1
anda.id2=b.id2
sessionB:
>deleteempwhereename='SCOTT';
deleteempwhereename='SCOTT'
*
ERRORatline1:
ORA-01013:
userrequestedcancelofcurrentoperation
sessionB:
>roll
Rollbackcomplete.
sessionB:
>
B执行ctrl+c中断并回滚锁被释放
LOOKC:
>select*fromv$lockwheresidin(151,146);
ADDRKADDRSIDTYID1ID2LMODEREQUESTCTIMEBLOCK
----------------------------------------------------------------------------------------
2F9C3F902F9C3FA8151TM511460203460
2F9C403C2F9C4054151TM511480303460
2FA259482FA25A64151TX196647370603460
LOOKC:
>
sessionB:
>deleteempwhereename='KING';
1rowdeleted.
sessionB:
>roll
Rollbackcomplete.
sessionB:
>
B再去删KING的行没问题因为这一行没有被锁oracle优势之一就是实现的是行级锁
sessionB:
>deletedeptwhere0=1;
被阻塞
LOOKC:
>select*fromv$lockwheresidin(151,146);
ADDRKADDRSIDTYID1ID2LMODEREQUESTCTIMEBLOCK
----------------------------------------------------------------------------------------
2F9C3F902F9C3FA8151TM511460204780
2F9C403C2F9C4054151TM511480304781
2F9C40E82F9C4100146TM51146030180
2F9C41942F9C41AC146TM51148004180
2FA259482FA25A64151TX196647370604780
LOOKC:
>
A的DEPT上的TM锁阻塞了一个会话从BLOCK1看出
这次的阻塞和外键有关系我们是可以提前避免这次的阻塞的,原因是外键上无索引
中断B
sessionB:
>deletedeptwhere0=1;
deletedeptwhere0=1
*
ERRORatline1:
ORA-01013:
userrequestedcancelofcurrentoperation
sessionB:
>roll
Rollbackcomplete.
sessionB:
>
回滚A
sessionA:
>roll
Rollbackcomplete.
sessionA:
>
释放所有锁,我们给外键加索引,重新开始刚才的测试
sessionA:
>createindexemp_deptno_idxonemp(deptno);
Indexcreated.
sessionA:
>deleteempwhereename='SCOTT';
1rowdeleted.
sessionA:
>
sessionB:
>deletedeptwhere0=1;
0rowsdeleted.
sessionB:
>
这次B没有被阻塞可见外键列有索引的必要性
自己用上面的例子试试选定更新意想行select...forupdate;(10GDML)
BJ==>GZ
1lock
select* from t1wherex=6;
select* from t1wherex=6forupdate;
就知道什么是selectforupdate了
selectforupdate选定有意向更新
TM锁本身不会对行上加锁,要区分表级锁和行级锁,
但是下图中的语句会同时触发表级锁和行级锁
语句类型
表级锁
行级锁
Insert
sx
Tx
Update
sx
Tx
Delete
sx
Tx
Selectforupdate
Ss(10g是sx)
tx
一个事务DML操作涉及了多少对象,就有多少个TM锁,我们可以通过参数限制这个TM锁数量
sessionB:
>showparameterdml_lock
NAMETYPEVALUE
-----------------------------------------------------------------------------
dml_locksinteger748
sessionB:
>
当改成0时就只有TX没有TM
sessionB:
>conn/assysdba
Connected.
sessionB:
>altersystemsetdml_locks=0scope=spfile;
Systemaltered.
sessionB:
>shutabort
ORACLEinstanceshutdown.
sessionB:
>startup
ORACLEinstancestarted.
TotalSystemGlobalArea285212672bytes
FixedSize1218992bytes
VariableSize96470608bytes
DatabaseBuffers184549376bytes
RedoBuffers2973696bytes
Databasemounted.
Databaseopened.
sessionB:
>updatescott.empsetsal=sal+1;
14rowsupdated.
sessionB:
>selectdistinctsidfromv$mystat;
SID
----------
159
sessionB:
>setline100
sessionB:
>select*fromv$lockwheresidin(159);
ADDRKADDRSIDTYID1ID2LMODEREQUESTCTIMEBLOCK
----------------------------------------------------------------------------------------
2F9E31AC2F9E32C8159TX6554930760510
sessionB:
>
但这种情况太极端了,数据库此时不能做DDL语句,当你的库确定不再做DDL时可以这样,很高效.
sessionB:
>droptablescott.emp;
droptablescott.emp
*
ERRORatline1:
ORA-00062:
DMLfull-tablelockcannotbeacquired;DML_LOCKSis0
sessionB:
>
把参数恢复成默认748.重新启库正常模式
DDL锁
DDL是数据字典锁数据字典中存在着对象的定义
防止表定义被并发更改
DDL锁分
专有锁
共享锁
可破碎的解析锁breakableparsedlock
当存储过程或执行计划产生时会在所涉及到的对象上加可破碎的解析锁
DDL专有锁
DDL锁存放在它引用的对象上的,以阻止在该对象上添加TM锁。
我droptable,altertable时你就不能再去修改表
DDL共享锁
DDL锁存放在它引用的对象上的,以阻止对象定义被改
我锁表定义你也可以锁表定义目的相同
比如:
同时两个用户在EMP表上创建一个存储过程
分别会在它引用的对象上(EMP)加一个DDL共享锁
而且用DML修改表的数据也允许
但不允许在EMP上修改表定义
DDL可破碎的解析锁
PL/SQL代码或sharedpool里的缓存的SQL游标使用对象时都需要对对象添加解析锁
当其他DDL修改了对象结构时,这个解析锁被打破,从而shared_pool中的SQL游标或存储过程会失效.
例如拿我们学过的创建视图来说,视图所引用的表上就添加了共享DDL锁,为防止创建视图的过程中其他用户来修改引用表的结构,但可以更新引用表数据
死锁
互相锁定的A锁BB锁A
死锁不需要我们维护oracle会自己维护
但我们要关注死锁避免死锁
oracle自维护的方法是将死锁的事务SQL级回退不是整个事务都回退
sessionA:
>createtablet3asselect*fromemp;
Tablecreated.
sessionA:
>
sessionA:
>createtablet4asselect*fromemp;
Tablecreated.
sessionA:
>updatet3setsal=sal+1whereename='SCOTT';
1rowupdated.
sessionA:
>
sessionB:
>updatet4setsal=sal+1whereename='SCOTT';
1rowupdated.
sessionB:
>
各自都有一个事务互不影响因为各自对象不同T3T4
交叉更新
A更新T4B更新T3
sessionA:
>updatet4setsal=sal+1whereename='SCOTT';
A被B的事务阻塞
updatet3setsal=sal+1whereename='SCOTT';
B又被A的事务阻塞
死锁产生oracle发现死锁会自己处理留下日志
[oracle@dba~]$cd$ORACLE_BASE/admin/$ORACLE_SID/bdump/
[oracle@dbabdump]$tailalert_ora10g.log
Completed:
ALTERDATABASEOPEN
TueMar811:
53:
592011
db_recovery_file_dest_sizeof2048MBis0.00%used.Thisisa
user-specifiedlimitontheamountofspacethatwillbeusedbythis
databaseforrecovery-relatedfiles,anddoesnotreflecttheamountof
spaceavailableintheunderlyingfilesystemorASMdiskgroup.
TueMar813:
02:
592011
ORA-00060:
Deadlockdetected.Moreinfoinfile/u01/oracle/admin/ora10g/udump/ora10g_ora_3319.trc.
[oracle@dbabdump]$
死锁不是数据库的错误是程序逻辑问题尽量避免事务占多个对象尽快提交缩短事务的周期
2锁的模式
2.1锁的模式
锁代码
锁模式名称
锁模式缩写
锁模式别名
锁级别
0
None
None
None
1
Null
Null
Null
表级锁
2
Row-s(ss)
Ss
Rs
表级锁
3
Row-x(sx)
Sx
Rx
表级锁
4
Share
S
S
表级锁
5
s/row-x(ssx)
Ssx
Srx
表级锁
6
exclusive
x
x
表级锁/行级锁
R是行,s是共享
2.2锁模式之间的兼容图
N
SS
SX
S
SSX
X
N
Yes
Yes
Yes
Yes
Yes
Yes
SS
Yes
Yes
Yes
Yes
Yes
No
SX
Yes
Yes
Yes
No
No
No
S
Yes
Yes
No
Yes
No
No
SSX
Yes
Yes
No
No
No
No
X
Yes
No
No
No
No
No
2.2.1锁代码0
0none没有锁没有资源竞争
2.2.2锁代码1
1null有空锁不产生资源竞争但做DDL操作要通知我
锁在SQL/PLSQL关联对象上学名:
BreakableParseLocks易破碎的解析锁
比如我们在存储过程里要引用t1表对它进行dml操作
如果我们某时,把它给drop了,那我们再执行这个存储过程时此时有提示说,表不存在
只要SQL/PLSQL在共享池,它将一直保持
上面两个知道就可以我们主要关注的是2-6号锁
2SS(RS)表级锁(表共享行共享)表定义被锁表内的行可以交易
SS=subsharetablelock
RS=RowShareTableLocks
selectforupdate10G前是SS锁10G开始变成SX三号锁(正式加入DML行列)
所以有些老资料把它当成是SS来讲(也是正确的)
10G前select...forupdate;
10G没有SQL自动产生
只能手动locktable...
sessionA:
>locktableempinrowsharemode;
Table(s)Locked.
sessionA:
>selectSESSION_ID,LOCK_TYPE,MODE_HELDfromdba_lockswhereSESSION_ID=159;
SESSION_IDLOCK_TYPEMODE_HELD
----------------------------------------------------------------------------
159DMLRow-S(SS)
sessionA:
>
此时和其他锁的兼容情况6号X被排除(等下介绍它)
DML都可以
但不能DDL
2.2.3锁代码3
3SX(RX)表级锁(表共享行排他)表定义被锁表内的涉及行被排他DML都会触发这种锁
SXsub_exclusive
RXROW_EXCLUSIVE
DML的触发会伴随着行排他TX
sessionA:
>updateempsetsal=sal+1whereename='SCOTT';
1rowupdated.
sessionA:
>selectSESSION_ID
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- lock