区:表空间中的基本单位

Oracle内核技术揭密_吕海波  学习笔记

oracle 10g中初始会为新建的表分配至少一个区,11.2.0.3版本之后不为新建表分配区,只有插入一条数据后才分配空间。

如下代码中,没有任何权限的ma账号,可以建表并指定表空间为tp,就说明此时是没有为表分配空间的,因为ma账号没有使用tp表空间的权限。当为ma账号授权并插入一条数据后,dba_extents中有数据了,说明这时是分配了空间的。

SQL> create user ma identified by ma;

User created.

SQL> create table ma.t60(id number(5),name varchar2(10)) tablespace tp;

Table created.

SQL> select  extent_id,file_id,block_id,blocks from dba_extents where segment_name='T60' order by extent_id;

no rows selected

SQL> insert into  ma.t60 values(1,'a1');
insert into  ma.t60 values(1,'a1')
                *
ERROR at line 1:
ORA-01950: no privileges on tablespace 'TP'


SQL> grant unlimited tablespace to ma;

Grant succeeded.

SQL> insert into  ma.t60 values(1,'a1');

1 row created.

SQL> select  extent_id,file_id,block_id,blocks from dba_extents where segment_name='T60' order by extent_id;

 EXTENT_ID    FILE_ID   BLOCK_ID     BLOCKS
---------- ---------- ---------- ----------
         0          4     327616          8

区是空间分配的基本单位,它分为统一区大小表空间和系统管理区大小表空间。

统一区大小表空间和区的使用规则:

创建一个数据文件大小为32M,区大小为1M的表空间,在此表空间中新建一张表,并插入一笔资料。可以看到这一笔资料放在7号数据文件的第128号到255号数据块中,共分配了128个数据块,每个块大小是8KB,128个块大小刚好是1MB,这是一个区的大小。

SQL>  CREATE TABLESPACE  TBS DATAFILE '/data1/oradata/ora1/tbs01.dbf' SIZE 32M uniform size 1M;

Tablespace created.

SQL> create table ma.t61(id number(5),name varchar2(10)) tablespace tbs;

Table created.

SQL> insert into  ma.t61 values(1,'a1');

1 row created.

SQL> select  extent_id,file_id,block_id,blocks from dba_extents where segment_name='T61' order by extent_id;

 EXTENT_ID    FILE_ID   BLOCK_ID     BLOCKS
---------- ---------- ---------- ----------
         0          7        128        128

 从上面代码可以看到第一个区是从128号块开始分配的,原因在于从11gR2开始,0-127号块被oracle留作内内部使用了,用于标记区的分配情况。0-1号块是文件头,2-127号块是位图块。其中第一个位图块,也就是2号块是位图段头,从3号块开如才是真正的位图数据。3-127号块共125个块,每个块8KB,共1000K字节,每字节有8位,共8000K字节,也就是可以记录8000K个区的分配情况。

在分配这些块时,oracle内部有一个标记位,0-2号块被使用了,标记位就先标记3号位,如果3-4号位又被占用了,就标记5号位;如果3号位现在被释放了,标记位会再标记3号位,当有请求分配数据块时,标记位就从当前位置向后查找并分配。

当开启了闪回drop时,如果drop了表,区是不会被释放的,标记位也不会下降,因为此时的drop只是改名,并没有真正删表。

系统管理区大小:

如下代码中,创建一个1G的表空间TBS2,在它上面建一张表t62,插入一笔数据后可以看到第一个区的大小为8个块,也就是64K。用insert into ... select语句往表中多次插入数据后,16号区的大小发生了变化,变为128个块,也就是1M的大小。如果数据继续增大,区大小将变为8M,后面还会增大。

SQL> CREATE TABLESPACE TBS2 DATAFILE '/data1/oradata/ora1/tbs201.dbf' SIZE 1G;
SQL> create table ma.t62(id number(5),name varchar2(10)) tablespace tbs2;
SQL> insert into ma.t62 values(1,'aa1');
SQL> commit;
SQL> select  extent_id,file_id,block_id,blocks from dba_extents where segment_name='T62' order by extent_id;

 EXTENT_ID    FILE_ID   BLOCK_ID     BLOCKS
---------- ---------- ---------- ----------
         0          8        128          8


SQL> insert into ma.t62 select * from ma.t62;

65536 rows created.

SQL> commit;
SQL> select  extent_id,file_id,block_id,blocks from dba_extents where segment_name='T62' order by extent_id;

 EXTENT_ID    FILE_ID   BLOCK_ID     BLOCKS
---------- ---------- ---------- ----------
         0          8        128          8
         1          8        136          8
         2          8        144          8
         3          8        152          8
         4          8        160          8
         5          8        168          8
         6          8        176          8
         7          8        184          8
         8          8        192          8
         9          8        200          8
        10          8        208          8
        11          8        216          8
        12          8        224          8
        13          8        232          8
        14          8        240          8
        15          8        248          8
        16          8        256        128

从上面的例子可知,表中只要有一笔数据进来,就会为这笔数据分配一个区的大小,因此小区比大区的空间利用率更高;但是当全表扫描时,大区可以减少磁头在区间的定位,可以提高性能。当然,对于随机访问,性能上就没有那么大的区别。

在使用统一区大小时,当段的大小超过64M,可以将区大小设为8M;很多系统一次I/O的最大读写数据量为1M,在一个8M的区里还是需要8次I/O,这时超过1M的区并不能减少I/O次数。当一次需要读取2M数据时,这2M数据又同时在一个8M的区里,这时虽然需要2次I/O,但是这是连续I/O;如果区大小只有1M,那么存这2M数据的区可能不连续,虽然也是2次I/O,但却可能是随机I/O,连续I/O性能要高于随机I/O性能。因此在使用统一区大小时,可以使用稍一点的区大小。

系统管理的区,在做位图标记时,以64K为准,也就是每一个位标记8个数据块的使用情况,如要分配1M的空间,需要修改16个标记位。

在统一区大小表空间中,由于每个区大小一样,被删掉的区可以重复使用,也就不存在碎片问题。但在系统管理区大小的表空间中,有很多64K的区,互相不连续,当分配1M这样的更大的区时,那些不连续的64K区无法被重用,这样就会存在碎片。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值