您的位置:首页 > 产品设计 > UI/UE

重复数据插入unique列时,锁加在哪?

2013-08-05 11:21 155 查看
1.测试目的

当插入重复数据到有unique索引的表中时,采用何种加锁机制。

2.测试思路

利用10046确定是什么操作导致加锁阻塞了进程;

dump锁定前最近一次操作的块结构来分析加锁机制。

3.测试环境

SQL>select*fromv$versionwhererownum=1;

BANNER

-----------------------------------------------------------------

OracleDatabase11gEnterpriseEditionRelease11.2.0.1.0-Production

4.测试过程

表test2及其索引idx_test2_id对应的object_id。

SQL>selectobject_id,object_namefromdba_objectswhereobject_namein('TEST2','IDX_TEST2_ID');

OBJECT_IDOBJECT_NAME

-------------------------

27667TEST2

27668IDX_TEST2_ID


--session1

SQL>insertintotest2values(1,'a');

已创建1行。

此处不提交。

--session2

SQL>altersystemflushbuffer_cache;

系统已更改。

SQL>altersessionsetevents‘10046tracenamecontextforever,level8’;

SQL>insertintotest2values(1,'a');

此处一直处于等待状态。

然后将session1提交,这时session2报错。

下面dump片断是在sesson2处于等待状态时的10046跟踪结果:

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

PARSINGINCURSOR#2len=31dep=0uid=34oct=2lid=34tim=10705648912hv=4047255222ad='277dc964'sqlid='9u2g41msmsdpq'

insertintotest2values(1,'a')

ENDOFSTMT

PARSE#2:c=15625,e=92942,p=0,cr=0,cu=0,mis=1,r=0,dep=0,og=1,plh=0,tim=10705648905

WAIT#2:nam='dbfilesequentialread'ela=22644file#=5block#=170050blocks=1obj#=27667tim=10705671989

WAIT#2:nam='dbfilesequentialread'ela=10704file#=5block#=170049blocks=1obj#=27667tim=10705682866

WAIT#2:nam='dbfilesequentialread'ela=299file#=5block#=170048blocks=1obj#=27667tim=10705683300

WAIT#2:nam='dbfilescatteredread'ela=25431file#=5block#=170051blocks=5obj#=27667tim=10705708852

WAIT#2:nam='dbfilesequentialread'ela=13716file#=3block#=256blocks=1obj#=0tim=10705722841

WAIT#2:nam='dbfilesequentialread'ela=15175file#=3block#=35109blocks=1obj#=0tim=10705738184

WAIT#2:nam='dbfilescatteredread'ela=22759file#=5block#=170056blocks=8obj#=27668tim=10705775416

WAIT#2:nam='dbfilesequentialread'ela=14768file#=3block#=160blocks=1obj#=0tim=10705790482

***2012-06-1311:15:22.984

WAIT#2:nam='enq:TX-rowlockcontention'ela=34452785name|mode=1415053316usn<<16|slot=196626sequence=906obj#=0tim=10740253456

WAIT#2:nam='latch:cachebufferschains'ela=44613address=783740924number=150tries=0obj#=0tim=10740298330

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

上面黑体部分,27667是表test2,27668是索引idx_test2_id,这个地方报等待事件“enq:TX-rowlockcontention”了。


下面这部分片断为session1提交后,session2报违反唯一性错误时的10046片断。

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

PARSINGINCURSOR#1len=84dep=1uid=0oct=3lid=0tim=10740356283hv=2686874206ad='29cece34'sqlid='2skwhauh2cwky'

selecto.name,u.namefromobj$o,user$uwhereo.obj#=:1ando.owner#=u.user#

ENDOFSTMT

PARSE#1:c=0,e=916,p=0,cr=0,cu=0,mis=1,r=0,dep=1,og=4,plh=0,tim=10740356276

EXEC#1:c=0,e=2776,p=0,cr=0,cu=0,mis=1,r=0,dep=1,og=4,plh=2024304382,tim=10740359417

WAIT#1:nam='dbfilesequentialread'ela=8833file#=1block#=337blocks=1obj#=36tim=10740368472

WAIT#1:nam='dbfilesequentialread'ela=18496file#=1block#=36489blocks=1obj#=36tim=10740387126

WAIT#1:nam='dbfilesequentialread'ela=13908file#=1block#=35771blocks=1obj#=18tim=10740401184

WAIT#1:nam='dbfilesequentialread'ela=6505file#=1block#=217blocks=1obj#=11tim=10740407986

WAIT#1:nam='dbfilesequentialread'ela=343file#=1block#=210blocks=1obj#=22tim=10740408476

FETCH#1:c=0,e=49001,p=5,cr=5,cu=0,mis=0,r=1,dep=1,og=4,plh=2024304382,tim=10740408587

STAT#1id=1cnt=1pid=0pos=1obj=0op='NESTEDLOOPS(cr=5pr=5pw=0time=0uscost=4size=45card=1)'

STAT#1id=2cnt=1pid=1pos=1obj=18op='TABLEACCESSBYINDEXROWIDOBJ$(cr=3pr=3pw=0time=0uscost=3size=27card=1)'

STAT#1id=3cnt=1pid=2pos=1obj=36op='INDEXRANGESCANI_OBJ1(cr=2pr=2pw=0time=0uscost=2size=0card=1)'

STAT#1id=4cnt=1pid=1pos=2obj=22op='TABLEACCESSCLUSTERUSER$(cr=2pr=2pw=0time=0uscost=1size=18card=1)'

STAT#1id=5cnt=1pid=4pos=1obj=11op='INDEXUNIQUESCANI_USER#(cr=1pr=1pw=0time=0uscost=0size=0card=1)'

CLOSE#1:c=0,e=341,dep=1,type=0,tim=10740409034

EXEC#2:c=15625,e=34772386,p=26,cr=9,cu=13,mis=0,r=0,dep=0,og=1,plh=0,tim=10740421590

ERROR#2:err=1tim=10740421776

STAT#2id=1cnt=0pid=0pos=1obj=0op='LOADTABLECONVENTIONAL(cr=0pr=0pw=0time=0us)'

WAIT#2:nam='SQL*Netbreak/resettoclient'ela=10driverid=1111838976break?=1p3=0obj#=0tim=10740422117

WAIT#2:nam='SQL*Netbreak/resettoclient'ela=311driverid=1111838976break?=0p3=0obj#=0tim=10740422539

WAIT#2:nam='SQL*Netmessagetoclient'ela=7driverid=1111838976#bytes=1p3=0obj#=0tim=10740422628


***2012-06-1311:15:34.718

WAIT#2:nam='SQL*Netmessagefromclient'ela=11554229driverid=1111838976#bytes=1p3=0obj#=0tim=10751976953

CLOSE#2:c=0,e=57,dep=0,type=0,tim=10751977262

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

上面黑体部分报错。该部分是在session1提交后,session2报违反唯一性错误。


下面dump结果为session2处于等待状态的时候的索引块状态,这个时候也正是读完表和索引后,进程正处于等待状态。那么这个时候的索引块状态足以说明Oracle在插入重复数据到具有uniqueindex索引的表中时是怎么处理的,是将锁加在索引还是表上。

索引块dump出结果分析:

DumpofFirstLevelBitmapBlock

--------------------------------

nbits:2nranges:1parentdba:0x01429849poffset:0

unformatted:4total:8firstusefulblock:3

owninginstance:1

instanceownershipchangedat06/12/201213:00:29

LastsuccessfulSearch06/12/201213:00:29

FreenessStatus:nf10nf21nf30nf40


ExtentMapBlockOffset:4294967295

Firstfreedatablock:3

Bitmapblocklockopcode9

Lockerxid::0x0003.011.000003b0

Inc#:0Objd:27772

HWMFlag:NotSet

Highwater::0x0142984cext#:0blk#:4extsize:8

#blocksinseg.hdr'sfreelists:0

#blocksbelow:1

mapblk0x00000000offset:0

--------------------------------------------------------

DBARanges:

--------------------------------------------------------

0x01429848Length:8Offset:0


0:Metadata1:Metadata2:Metadata3:25-50%free

4:unformatted5:unformatted6:unformatted7:unformatted

--------------------------------------------------------

Enddumpdatablockstsn:4file#:5minblk170056maxblk170056

从上面索引块dump出的结果看,在索引块上加了锁。

5.测试结果分析

由以上测试过程总结:

当插入数据到有unique索引的表并且进程未提交,这时再有其他进程插入重复数据到该表时。Oracle首先将数据写入到数据块,在维护索引叶子节点时发现已经有相同的数据在索引块中存在,则会在索引块上加锁并阻塞进程。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: