天天看点

测量block size 为8K ,自动分配的本地管理表空间的位图block一位能管理多少空间

从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,自动分配,本地管理的表空间呢?其实原理也应该是同样的,一位能管理多少空间应该取决于最小的一个区间的值。