服务器进程寻找空闲块的步骤:
ITPUB个人空间p lP\9]6^}8jWl
在ASSM表空间中,执行Insert声明时,Oracle是如何为声明分配可用块的?
-Y@X-`5F"p8AVA0
以前已经有网友论证,在ASSM中,可用块的管理,由L3、L2和L1三级位图块实现。具体的步骤就是,先通过数据字典找到段头,而段头其实就是表的第一个L3块,在其中寻找L2。根据执行插入声明的服务器进程的PID,计算出一个随机HASH值,根据此HASH值,在L2中找到一个L1。再根据服务器进程的PID,在L1中查找一个可用的数据块,并在其中插入新行。具体的步骤如下:
ITPUB个人空间o~7JH
GR8f
步1:
ITPUB个人空间gQ`wT G L
我的实验环境如下:
S:t%cwI#A
}H0
块大小:8K;区大小40K;实验表现占5个区;
ITPUB个人空间&sq'|-nj2q dR
假设现在用户端发来命令如下:
ITPUB个人空间~
A U/`%iDz)[1d
Insert into new01_jj_1 values(1,’a’);
h
P'D4P-Co0
首先,对于new01_jj_1,数据库并不理解这是什么,Oracle首先要去查询数据字典表,了解这一串字母的具体意义,例如,Oracle要确定这是一个视图、同义词,或是一个表等等,这些操作,就是递归操作,我们只拣和我们今天的论题相关的说,Oracle要先查找seg$数据字典表,找出段头的文件号和块号,我们将这一步操作化为对基于seg$数据字典表的视图:Dba_segments的操作:
'@b*C4c2E/Q8[U/f
s0
SQL> select header_block,header_file,segment_type from dba_segments where segment_name='NEW01_JJ_1';
`m5C*V!hm
}0
HEADER_BLOCK HEADER_FILE SEGMENT_TYPE
ITPUB个人空间2H/GY9g#NE
------------ ----------- ------------------
(jE#GBJb7tK{)D0
11 9 TABLE
ITPUB个人空间/A)`2BRnW
步2:根据上面的显示结果可知,段头是在9号文件的第11号块,段头是第一个L3块,在L3中保存着L2块的地址,L2块保存着L1块的地址,L1块保存着数据块的地址。所以想查找数据库的第一步,就是要先找到L3块,并在其中搜索可用的L2块,下面我们转储表的第一个L3块,即段头:9号文件11号块,然后在其中搜索可用的L2块。
ITPUB个人空间Lfmhu;CA
转储命令如下:
-_En5qFa"B0}Pm?0
SQL> alter system dump datafile 9 block 11;
,H3a"ts0v'l
{%pw+v0
系统已更改。
&z)N ge/\X-W0
转储结果如下:
+{L8f-O
x0B4o&|0
*** 2008-02-15 13:46:50.562
[ \;N*g:q5a/Lc|m
g0
*** SERVICE NAME

SYS$USERS) 2008-02-15 13:46:50.515
)w4n.Jn7s;`IIB
S0
*** SESSION ID

206.4) 2008-02-15 13:46:50.515
ITPUB个人空间3@k8o6CE!]$@$N
Start dump data blocks tsn: 11 file#: 9 minblk 11 maxblk 11
vBhe7w)F&KzG!s0
buffer tsn: 11 rdba: 0x0240000b (9/11)
px1}9K:C;V+_0
scn: 0x0000.001e0767 seq: 0x01 flg: 0x04 tail: 0x07672301
V;w-c cmnH,B5v0
frmt: 0x02 chkval: 0x604a type: 0x23=PAGETABLE SEGMENT HEADER
;sUl3~"Z,H^0
Extent Control Header
ITPUB个人空间H
` w.Q'h-xQ+Z
-----------------------------------------------------------------
n6_0kEW-n0
Extent Header:: spare1: 0 spare2: 0 #extents: 5 #blocks: 25
ITPUB个人空间 N2HvYu b
last map 0x00000000 #maps: 0 offset: 2716
ITPUB个人空间X ]r/P3FET
Highwater:: 0x02400027 ext#: 4 blk#: 5 ext size: 5
lPL(J5h+GyD0
#blocks in seg. hdr's freelists: 0
K3V{1U0ODW3~q0
#blocks below: 21
0Y5q;Bb
TtV0
mapblk 0x00000000 offset: 4
ITPUB个人空间o!s1VGnv#{G7Kg|
Unlocked
|"Ae*Lm4~$eF0
--------------------------------------------------------
H^'wc7N0X0
Low HighWater Mark :
1fp$]nQj"e0
Highwater:: 0x02400027 ext#: 4 blk#: 5 ext size: 5
[6_N
_1g0
#blocks in seg. hdr's freelists: 0
h1a7jZp~0
#blocks below: 21
kHxu2?0
mapblk 0x00000000 offset: 4
/zS-Q H q}0cVU0
Level 1 BMB for High HWM block: 0x0240001d
#[gXhf;o0
Level 1 BMB for Low HWM block: 0x0240001d
ITPUB个人空间;gt#Q
O;Ee
--------------------------------------------------------
ITPUB个人空间0i$uy$~E%P)P!y
Segment Type: 1 nl2: 1 blksz: 8192 fbsz: 0
~&jZ%K"`{0
L2 Array start offset: 0x00001434
ITPUB个人空间3V8B#G]-XT
First Level 3 BMB: 0x00000000
J
nlo{m$nq0
L2 Hint for inserts: 0x0240000a
mH+S_EUR0
Last Level 1 BMB: 0x0240001d
ITPUB个人空间#Z0gd%Wk7CY"O E
Last Level II BMB: 0x0240000a
F~U+R9vk@0
Last Level III BMB: 0x00000000
6p]
[%n3zqG3zm"@4E
`$C0
Map Header:: next 0x00000000 #extents: 5 obj#: 52176 flag: 0x10000000
[[-C"q)P_0
Inc # 0
!d
M?V7x&Zj6A}0
Extent Map
}"P'?)z&ly W9J4H0
-----------------------------------------------------------------
ITPUB个人空间.qig Y.n
0x02400009 length: 5
+Z9wf:Oq&b\0
0x0240000e length: 5
ITPUB个人空间A!^mv TQ
0x02400018 length: 5
ITPUB个人空间
x(B/n&Su*C
0x0240001d length: 5
ITPUB个人空间9~#k1E,L@
0x02400022 length: 5
ITPUB个人空间,M| \|2u["|
R/tCn.C p,c0
Auxillary Map
ITPUB个人空间s?%~
hu-I[
K
--------------------------------------------------------
+G'|(r)g8S$c6p)[
^Q0
Extent 0 : L1 dba: 0x02400009 Data dba: 0x0240000c
:[}5J1B"XB#v}Dc2EuD%A0
Extent 1 : L1 dba: 0x02400009 Data dba: 0x0240000e
kk q"ueuLU-h$i0
Extent 2 : L1 dba: 0x02400009 Data dba: 0x02400018
ITPUB个人空间
_(OT'^nb4] x
Extent 3 : L1 dba: 0x0240001d Data dba: 0x0240001e
}tprY Wu0
Extent 4 : L1 dba: 0x0240001d Data dba: 0x02400022
ITPUB个人空间3Bp5f(ubIMO*QF6E
--------------------------------------------------------
ITPUB个人空间Rs7b8v/`?,hsM.P
rg5y ZN nuK%c0
Second Level Bitmap block DBAs
@*WX]
d1d7m;]l0
--------------------------------------------------------
7PW5I$\:g Yt6Fe
~0
DBA 1: 0x0240000a
ITPUB个人空间,E6MHup
ITPUB个人空间Jz-S|?/?!Z^
End dump data blocks tsn: 11 file#: 9 minblk 11 maxblk 11
VgW\)GD7o/S%p0
ITPUB个人空间.b@#yk1C*wl
查看上面的信息,可知现在表New01_jj_1表中只有一个L2块,即9号文件第10号块。将来随着表的增大,L1块的增多,L2块也会逐步增多。那么,在L3中记录的L2也会随之增多,如何在众多L2块中快速找到一个可用的L2块呢?Oracle专门增设了一个L2 Hint for inserts,此处的值为0x0240000a,即第9号文件10号块。我们可以直接根据L2 Hint for inserts中的指示,找出可用的L2块,此处为第9号文件10号块,这就是在L3中查找L2的步骤,下面,我们转储L2,并在其中查找L1块。
ITPUB个人空间a7nT dhK)?i"_
步3:转储L2块9号文件10号块:
%vt m,J}Yz1JAL0
SQL> alter system dump datafile 9 block 10;
ITPUB个人空间 i,gTI2S{Ss v5J
系统已更改。
7QG/X _7e6\WN0
*** 2008-02-15 13:52:03.359
ITPUB个人空间w)i$c@9w
ygn:T:e }
Start dump data blocks tsn: 11 file#: 9 minblk 10 maxblk 10
fyp}C0
buffer tsn: 11 rdba: 0x0240000a (9/10)
ITPUB个人空间-O:p/JBY!n6r"J`
scn: 0x0000.001e0767 seq: 0x01 flg: 0x04 tail: 0x07672101
7v7fT"g^R]'L0
frmt: 0x02 chkval: 0x4cfb type: 0x21=SECOND LEVEL BITMAP BLOCK
ITPUB个人空间q0C
Jv%q7kyAiz
$]BU&pK5XD"L0
Dump of Second Level Bitmap Block
ITPUB个人空间tU
n
|p P5_a#qh
number: 2 nfree: 1 ffree: 1 pdba: 0x0240000b
V l)S|5Q-QyM0
Inc #: 0 Objd: 52176
s9`%y]DF2{0
opcode:0
ITPUB个人空间&p&\7fn0u.nmO8V
xid:
ITPUB个人空间'\Nw2O6T$o
L1 Ranges :
5E:JZ8dO{y0
--------------------------------------------------------
e
T
|X.g.Pq0
0x02400009 Free: 1 Inst: 1
ITPUB个人空间1A]5[iv3z
0x0240001d Free: 3 Inst: 1
ITPUB个人空间&kO/Ndp1Gh
ITPUB个人空间7Okr
wQ6Q
--------------------------------------------------------
ITPUB个人空间L D!o%f6tM
End dump data blocks tsn: 11 file#: 9 minblk 10 maxblk 10
7O)w*uR.~ n0
这里我们看到 L2块中有两个L1块 分别是 9号块 和 29号块,到这一步,Oracle如何在L2中选择L1?为了提高插入的并行度,这里将根据完成插入操作服务器进程的PID,计算出一个Hash值,根据此Hash值在多个L1中选择一个。也就是在多个L1中根据进程PID随机选择一个。此处要注意的是,高高水点(不是输入错误,高水点在ASSM中有两个:低高水点和高高水点)之后的块不在选择范围内。
ITPUB个人空间a&K'}+s?@)f-f
如果从两个会话中插入,Oracle会尽量将这两个进程分配到两个L1块中。
ITPUB个人空间x!mu|6~Yct
假设,这里选择了29号,我们再来转储它。
ITPUB个人空间)^7_7Y!},z;R:}4zm
步4:
ITPUB个人空间}:IH4Tr)|0|
SQL> alter system dump datafile 9 block 29;
js @
xh9y0
系统已更改。
ITPUB个人空间W7N$h)y%^m
*** 2008-02-15 14:00:26.078
ITPUB个人空间r)Y8},}HT&\
Start dump data blocks tsn: 11 file#: 9 minblk 29 maxblk 29
7O!O%e~pH3J4ew0
buffer tsn: 11 rdba: 0x0240001d (9/29)
%rA HO"fi8A0
scn: 0x0000.001e0767 seq: 0x0c flg: 0x04 tail: 0x0767200c
Ri]Dv_0
frmt: 0x02 chkval: 0x4faa type: 0x20=FIRST LEVEL BITMAP BLOCK
#RmTm,u+EhID5V `$A0
Dump of First Level Bitmap Block
pQ#GugN%]0
--------------------------------
W"`W@8YsnU0
nbits : 4 nranges: 2 parent dba: 0x0240000a poffset: 1
ITPUB个人空间D1rYAbf"{
unformatted: 0 total: 10 first useful block: 1
g,r*d
~g"e y6`)G0
owning instance : 1
ITPUB个人空间r,Ecn6s0u
instance ownership changed at 02/15/2008 12:01:34
ITPUB个人空间 hq;b? E b
Last successful Search 02/15/2008 12:01:34
3w%EK+Y4|puS `
\0
Freeness Status: nf1 0 nf2 1 nf3 0 nf4 0
ITPUB个人空间;y;S0sH*I1Ua
Iqm
&\.G6r0D
m A7{7f0
Extent Map Block Offset: 4294967295
`5e%zl`D!jNXj7j7k0
First free datablock : 5
ITPUB个人空间5Hr8b!D*c:fVnC
Bitmap block lock opcode 0
h@ P&NU:w0
Locker xid: : 0x0000.000.00000000
8Mk)_A*snh0
Inc #: 0 Objd: 52176
ITPUB个人空间R n:v/\vG
HWM Flag: HWM Set
ITPUB个人空间0Wo5j],Fu `
nT:^zL
Highwater:: 0x02400027 ext#: 4 blk#: 5 ext size: 5
ITPUB个人空间xS9Y&Ap1[`]w
#blocks in seg. hdr's freelists: 0
i9qt/gJ0
#blocks below: 21
7jB8Jm g0
mapblk 0x00000000 offset: 4
)C-nU0WU\n^0
--------------------------------------------------------
'T9E|2T]7E-[0
DBA Ranges :
]0E-@t1IL'DU0
--------------------------------------------------------
ITPUB个人空间.BLX8SL*Q.|V#H
0x0240001d Length: 5 Offset: 0
ITPUB个人空间'I_o(pe+Gfxa7HA
0x02400022 Length: 5 Offset: 5
6X9ILZ4W0
ITPUB个人空间E^"^I
rXD
0:Metadata 1:FULL 2:FULL 3:FULL
ITPUB个人空间sJF$hF5c`y|
4:FULL 5:25-50% free 6:FULL 7:FULL
ITPUB个人空间9}+IfC-vS:l-s
pS
8:FULL 9:FULL
h"Qw]7L0iS*j#`0
--------------------------------------------------------
ITPUB个人空间4{+ep+O*\d(U
End dump data blocks tsn: 11 file#: 9 minblk 29 maxblk 29
Pk^)w(BM0
此L1块中包含10个数据块,在这10个块中的选择,Oracle也是根据进程的PID,随机挑选。同样,两个不同进程发布的插入,Oracle会尽量使其插入进不同的数据块中,以提高并发性。