從oracle8i起,oracle推出了本地管理表空間的來代替資料字典管理的表空間,資料字典管理表空間是用uet$,fet$這兩個表來管理的,它們現在依然存在于資料庫中,不過不起任何作用。
SQL> select count(*) from uet$;
COUNT(*)
----------
SQL> select count(*) from fet$;
下面來探究自動配置設定的本地管理表空間中一個bit map block 的一bit能管理多少?
SQL> select * from v$version;
BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - Prod
PL/SQL Release 10.2.0.3.0 - Production
CORE 10.2.0.3.0 Production
TNS for 32-bit Windows: Version 10.2.0.3.0 - Production
NLSRTL Version 10.2.0.3.0 - Production
SQL> show parameter db_block_size
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
db_block_size integer 8192
SQL> create tablespace lmt datafile 'C:/ORACLE/PRODUCT/10.2.0/ORADATA/ROBINSON/DATAFILE/lmt.dbf' size 20m extent
2 management local autoallocate;
Tablespace created
SQL> create table test(name varchar2(20)) tablespace lmt;
Table created
SQL> select segment_name,tablespace_name,header_file,header_block,blocks from dba_segments where tablespace_name='LMT';
SEGMENT_NA TABLESPACE_NAME HEADER_FILE HEADER_BLOCK BLOCKS
---------- -------------------- ----------- ------------ ----------
TEST LMT 6 11 8
可以看到表test位于LMT表空間,他的檔案号為6,段頭為11,知道ASSM段管理方式的人都知道,段頭是第三個位圖塊,是以這裡第9個block是一級位圖塊,第10個block是二級位圖塊,是以我們知道oracle預留下了8個block來管理這個資料檔案。
SQL> alter system dump datafile 6 block min 1 block max 11;
System altered
部分DUMP檔案
Start dump data blocks tsn: 10 file#: 6 minblk 1 maxblk 11
Block 1 (file header) not dumped: use dump file header command
-----第一個block沒有dump出來
buffer tsn: 10 rdba: 0x01800002 (6/2)
scn: 0x0000.001bb0c6 seq: 0x02 flg: 0x04 tail: 0xb0c61d02
frmt: 0x02 chkval: 0xbbb2 type: 0x1d=KTFB Bitmapped File Space Header
Hex dump of block: st=0, typ_found=1
Dump of memory from 0x094AFE00 to 0x094B1E00
94AFE00 0000A21D 01800002 001BB0C6 04020000 [................]
94AFE10 0000BBB2 00000006 00000008 00000A00 [................]
94AFE20 00000001 00000000 00000000 00000007 [................]
94AFE30 00000A00 00000001 0000013E 00000000 [........>.......]
94AFE40 00000000 00000000 00000000 00000000 [................]
94AFE50 00000009 00000008 00000000 00000000 [................]
94AFE60 00000000 00000000 00000000 00000000 [................]
Repeat 504 times
94B1DF0 00000000 00000000 00000000 B0C61D02 [................]
File Space Header Block:
----1,2兩個塊是資料檔案的塊頭
Header Control:
RelFno: 6, Unit: 8, Size: 2560, Flag: 1
AutoExtend: NO, Increment: 0, MaxSize: 0
Initial Area: 7, Tail: 2560, First: 1, Free: 318
Deallocation scn: 0.0
Header Opcode:
Save: No Pending Op
buffer tsn: 10 rdba: 0x01800003 (6/3)
scn: 0x0000.001bb0c6 seq: 0x01 flg: 0x04 tail: 0xb0c61e01
frmt: 0x02 chkval: 0x4e76 type: 0x1e=KTFB Bitmapped File Space Bitmap
94AFE00 0000A21E 01800003 001BB0C6 04010000 [................]
94AFE10 00004E76 00000006 00000009 00000000 [vN..............]
94AFE20 00000001 0000F7FF 00000000 00000000 [................]
94AFE30 00000000 00000000 00000001 00000000 [................]
Repeat 506 times
94B1DF0 00000000 00000000 00000000 B0C61E01 [................]
File Space Bitmap Block: ----從第三個block開始,就是本地管理表空間的位圖塊
BitMap Control:
RelFno: 6, BeginBlock: 9, Flag: 0, First: 1, Free: 63487
0100000000000000 0000000000000000 0000000000000000 0000000000000000
0000000000000000 0000000000000000 0000000000000000 0000000000000000
...................省略若幹.................
SQL> select segment_name,extent_id,file_id,block_id from dba_extents where segment_name='TEST' and file_id=6;
SEGMENT_NA EXTENT_ID FILE_ID BLOCK_ID
---------- ---------- ---------- ----------
TEST 0 6 9
First=1表示配置設定了1個bit,這裡配置設定了一個64K的空間,也就是說配置設定了1個區,因為是自動擴充,那麼第一個區為64K。
下面向表TEST多插入10萬行資料
SQL> begin
2 for i in 1..100000 loop
3 insert into test values('robinson') ;
4 end loop;
5 commit;
6 end;
7 /
PL/SQL procedure successfully completed
SQL> select extent_id,blocks from dba_extents where file_id=6;
EXTENT_ID BLOCKS
---------- ----------
0 8
1 8
2 8
3 8
4 8
5 8
6 8
7 8
8 8
9 8
10 8
11 8
12 8
13 8
14 8
15 8
16 128 ----注意這裡一個區為128個blok,那麼一共有32個區為64K的空間
17 rows selected
插入10W行資料之後,TEST表所在的資料檔案配置設定了17個區,一共有256個block,也就是說配置設定了256*8=2048K,
現在我們dump datafile 6 block 3
SQL> alter system dump datafile 6 block 3;
系統已更改。
部分的DUMP檔案
Start dump data blocks tsn: 10 file#: 6 minblk 3 maxblk 3
scn: 0x0000.001bc284 seq: 0x01 flg: 0x00 tail: 0xc2841e01
frmt: 0x02 chkval: 0x0000 type: 0x1e=KTFB Bitmapped File Space Bitmap
Dump of memory from 0x07CE7800 to 0x07CE9800
7CE7800 0000A21E 01800003 001BC284 00010000 [................]
7CE7810 00000000 00000006 00000009 00000000 [................]
7CE7820 00000020 0000F7E0 00000000 00000000 [ ...............]
7CE7830 00000000 00000000 FFFFFFFF 00000000 [................]
7CE7840 00000000 00000000 00000000 00000000 [................]
7CE97F0 00000000 00000000 00000000 C2841E01 [................]
File Space Bitmap Block:
RelFno: 6, BeginBlock: 9, Flag: 0, First: 32, Free: 63456
FFFFFFFF00000000 0000000000000000 0000000000000000 0000000000000000
............................省略若幹...................................................................
First=32是以,這裡一共配置設定了32bit,但是根據上面的查詢,一共配置設定了17個區,17個區一共等于2048K,2048/32=64,猜測一bit能管理64K
下面插入100W行資料測試一下
2 for i in 1..1000000 loop
3 insert into test values('luoluo');
16 128
17 128
18 128
19 128
20 128
21 128
22 128
23 128
24 128
25 128
26 128
27 128
28 128
29 128
30 rows selected
可以看到配置設定了16*8+14*128=1920個block,也就是1920*8= 15360K,下面dump一下datafile 6 block 3看看first是否等于15360/64=240
部分dump檔案
scn: 0x0000.001c1595 seq: 0x01 flg: 0x04 tail: 0x15951e01
frmt: 0x02 chkval: 0xb191 type: 0x1e=KTFB Bitmapped File Space Bitmap
Dump of memory from 0x04807800 to 0x04809800
4807800 0000A21E 01800003 001C1595 04010000 [................]
4807810 0000B191 00000006 00000009 00000000 [................]
4807820 000000F0 0000F710 00000000 00000000 [................]
4807830 00000000 00000000 FFFFFFFF FFFFFFFF [................]
4807840 FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF [................]
4807850 FFFFFFFF 0000FFFF 00000000 00000000 [................]
4807860 00000000 00000000 00000000 00000000 [................]
48097F0 00000000 00000000 00000000 15951E01 [................]
RelFno: 6, BeginBlock: 9, Flag: 0, First: 240, Free: 63248
FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFF0000
果然First等于240,恩還得繼續
下面插入500W行再測試一下
SQL> alter database datafile 'C:/ORACLE/PRODUCT/10.2.0/ORADATA/ROBINSON/DATAFILE/LMT.DBF' autoextend on maxsize 100m;
Database altered
SQL> alter table test nologging;
Table altered
SQL>
2 for i in 1..5000000 loop
SQL> select sum(blocks) from dba_extents where file_id=6;
SUM(BLOCKS)
-----------
11264
可以看到一共配置設定了11264個block,那麼dump 一個datafile 6 block 3 ,看看First是否等于11264/8=1048
scn: 0x0000.001d0f53 seq: 0x01 flg: 0x04 tail: 0x0f531e01
frmt: 0x02 chkval: 0x4e8f type: 0x1e=KTFB Bitmapped File Space Bitmap
4807800 0000A21E 01800003 001D0F53 04010000 [........S.......]
4807810 00004E8F 00000006 00000009 00000000 [.N..............]
4807820 00000580 0000F280 00000000 00000000 [................]
Repeat 9 times
48078E0 FFFFFFFF FFFFFFFF 00000000 00000000 [................]
48078F0 00000000 00000000 00000000 00000000 [................]
Repeat 495 times
48097F0 00000000 00000000 00000000 0F531E01 [..............S.]
RelFno: 6, BeginBlock: 9, Flag: 0, First: 1408, Free: 62080
FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF
FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF 0000000000000000 0000000000000000
果然如此,再繼續插入我就吃不消了,剛才足足耗費了8分鐘才完成插入500W行
由此可以猜測在block size =8K, 自動配置設定,本地管理的表空間中,位圖的一位表示64K,因為不管你怎麼配置設定,都要配置設定一個64K的區。那block size 為16K/32k,自動配置設定,本地管理的表空間呢?其實原理也應該是同樣的,一位能管理多少空間應該取決于最小的一個區間的值。