当一个用户被创建之后, 随之就要为用户分配数据存储的空间, 称为表空间. 用于存储永久数据的 永久表空间, 用于存储临时数据的表空间 临时表空间.

1. 表空间的创建(推荐使用toad)

create tablespace USER_LEON

datafile '/opt/oracle/oradata/leon/leon01.dbf' size 10M

EXTENT management LOCAL uniform size 128k

segment space management auto;

 

select tablespace_name, block_size, contents, extent_management, allocation_type, segment_space_management

from dba_tablespaces where tablespace_name = 'LEON';

2. 完整的为应用创建需要的用户和空间

1) 创建application对应的表空间

create tablespace USER_LEON

datafile '/opt/oracle/oradata/leon/leon01.dbf'

size 100M autoExtend on next 10M maxsize 2048M

extent management local uniform size 128k

segment space management auto;

2) 创建用户, 并制定缺省的永久表空间和临时表空间

create user leon identified by leon

default tablespace USER_LEON

temporary tablespace temp;

3) 分配和收回 resource

grant connect, resource to leon;

revoke unlimited tablespace from leon;

alter user leon quota unlimited to USER_LEON;  -- 只分配给用户应该有的权限 resource

3. 本地表空间管理办法(extent)

现在都是用这种, 对比数据字典管理表空间办法, 所谓本地化管理, 就是指 Oracle 不再利用数据字典来记录Oracle表空间里面的区间的使用情况, 而是在每个表空间的数据文件的头部加了一个位图区域, 在其中记录每个Extent的使用情况, 每当一个 Extent被使用, 或者被释放以供重新使用时, Oracle都会更新数据文件头部的这个记录, 反映这个变化.

需要注意的是, 在创建本地管理表空间时, 还可以选择更具体的分配方式, 自动分配(autoallocate)还是统一分配(uniform). 关于这两种形式的选择:

autoallocate: 管理的比较少, 小表比较适合.

uniform: 管理的比较多的, 这种的特点是碎片化小.

所以, 如果表比较小, 将来可预见的增长也很少, 索性就用 autoallocate, 如果表很大, 就用 uniform.

dba_extents 这个重要视图记录了每个对象分配的区间.

4. 段空间管理技术

在 oracle 数据库内部, 对象空间是以段的形式(segment)存在和管理的.

当一个段被创建时, 区间(extent)就被分配, 随着后续的不断使用, 一个段的空间可以以区为单位不断扩展.

“segment space management auto” 这句话就是定义段的空间管理方式.

区间extent: oracle 最小空间分配单位

块block: oracle 最小I/O操作单位.

ASSM: 自动段空间管理技术.

5. 存储信息

oracle 最小的数据存储单位是数据块, 如果以单个数据块(block)进行对象空间分配, 那么显然分配过于频繁, 所以oracle使用多个数据块组成了区间(extent), 区间是oracle数据库对象的最小空间分配单位, 对象的空间分配和扩展只能以区间为单位进行, 多个区间组成了段(segment), 根据用途不同, oracle数据库又存在不同的段类型(table, table partition, cluster, index, undo segment, temporary segment, LOB segement 等等), 段存储在表空间中, 一个数据库最终由一系列的表空间构成.

dba_tablespaces

dba_data_files

dba_segments

以上信息, 通过 toad 查询更方便.

这里引入一个新的概念,对于MSSM方式管理的Segment,高水位标记(High Water Mark, HWM), 在HWM以上的数据块未格式化之前是不能被insert数据的, 在数据库事务中, 当请求新的空闲块并且现有空闲列表(free list)中的块不能满足要求时, HWM将会向上移动, 然后格式化一组数据块并加入FreeList提供使用. 在HWM之下的数据块也可能存在空闲情况, 当数据被删除之后, 数据块被释放重新回到空闲列表, 又可以被其他数据变更所使用, HWM通常只会向上增长, 不会自动收缩. truncate 会让HWM 收缩. HWM 会影响 oracle 执行全表扫描时的读取行为, 对于全表扫描操作, oracle必须读取HWM 下的所有数据块, 如果一个数据表由于 delete 操作删除了大部分记录, 但是 HWM 并不会降低, 所以再次执行全表扫描时, oracle 仍然需要读取对象段中的所有数据块, 这显然会影响性能.

6. Resizing a Tablespace

当表空间不够用时, 你可以有两种办法扩大tablespace:

1) change the size of data file, either automatically or manually. ( manually 可以变小, 变小时要看datafile的存储情况, 比如有个500M的datafile, 你想变成200M, 这时就要看这个datafile的真正存储情况了, 如果它存储的内容小于 200M, OK 如果大于200M就玩了)

  alter database datafile '/u01/oradata/dbhz01/userdata01.dbf' size 200M autoextend on | off next 10M maxsize 500M;

  alter database datafile '/u01/oradata/userdata02.dbf' resize 200M;  -- 缩小了, 手动修改

2) add data file to a tablespace.

  alter tablespace userdata add datafile '/u01/oradata/dbhz01/userdata03.dbf' size 300M; -- 增加一个 datafile.

  个人感觉: 我们不用管哪个datafile具体存储哪些segment,因为segment本身就可以横跨datafile, 这是一种抽象, 我们只需要知道哪个Object 比如哪个table存储在这个tablespace下就可以了, 另外这个tablespace有哪些datafile, 置于table 和 datafile的对应关系我们不用去管.