该片博文使用与入门学习表空间的理论,本文背景是10G-11.2G。关注博主后续推出表空间的管理!


表空间的特性与作用

表空间的特性

   表空间是数据库中最大的逻辑结构,用来存放数据的数据。表空间是由至少一个数据文件组成。一个数据文件只能属于一个表空间,一个表空间只能属于一个数据库。存放数据库对象(表、索引、视图、过程、函数等)

表空间的作用

  • 控制数据库所占用的磁盘空间;

  • 控制用户所占用的表空间配额;

  • 将不同表的数据、分区表的不同分区的数据放到不同表空间(或相同表空间不同的数据文件)中可以提高I/O性能。还放利于备份、管理等工作;

  • 将一个表的数据和索引分别存放在不同的表空间(或相同表空间不同的数据文件)可以提高I/O性能;

  • 可以设置只读状态保持大量的静态数据;

  • 可以按表空间来备份恢复;

表空间的结构

   表空间可以从以下两个结构来切入了解。

   逻辑:表空间实际是由一个或多个数据文件组成,数据文件是存储在相同或不同物理磁盘上可以看到的文件。从下图中可以清楚的看到物理结构的关系,其实从物理结构来理解,数据库中所有的数据就是存储在数据文件中。

   对于数据库来说表空间就是最大的逻辑结构。在表空间中最先的单位是Oracle块,而一系列连续的块组成一个区,多个区组成段,多个段组成表空间。

image.png


   从逻辑理解表空间可以由下图来解析,表空间中最小的单位就是Oracle块,一系列连续的块分组为区间,多个区间组成一个段。段是表空间中逻辑上最大的单位。反过来理解就是表空间逻辑由段空间组成,段空间主要是管理所有Oracle块的,而一个段中的块特别多,每次管理一个块空间过于耗时,所以我们将段中一系列连续块分组为区间来管理。

块:实际存储数据的地方。在定义了每次扩展区的大小其实就是定义多少个块给一个区。

区间:一系列连续编号块的集合。段每次扩展空间都是一个区间一个区间的扩展的空间。

段:由一个个区间组成。在创TABLE、INDEX、LOBINDEX、INDEX PARTITION、NESTED TABLE、TABLE PARTITION、ROLLBACK、LOB PARTITION、LOBSEGMENT、CLUSTER、TYPE2 UNDO时就会为其分配一个段。

image.png


表空间类型

系统表空间

   系统表空间包括SYSTEM表空间和SYSAUX表空间这两个必须存在的,其余的都是非系统表空间。系统表空间是数据库必须有的表空间,在建库时自动创建的。一般存放Oracle的数据字典和字典数据。

永久表空间

   永久表空间主要存放永久保存的数据,如果系统数据、应用系统的数据。每个用户都会拥有一个永久表空间,用于存方案对象的数据。除了撤销表空间和临时表空间其它的都是永久表空间。在BDCA建库后系统也会自动创建一个USERS永久表空间。

当创建用户时没有指定默认的永久表空间时,系统默认指定使用USERS永久表空间。(用下面命令可以查看默认指定的永久表空间)

(select * from database_properties where property_name='DEFAULT_TEMP_TABLESPACE';)

临时表空间

   用于存放临时数据,当在执行group by、order by、create index等功能的sql语句时,会产生大量的临时数据。这些临时数据会存放在PGA中,当PGA不够用时就会在存放到临时表空间中。在BDCA建库后系统也会自动创建一个TEMP临时久表空间。

   当创建用户时没有指定临时表空间时,系统默认指定使用TEMP临时表空间。(用下面命令可以查看默认指定的临时表空间)

select * from database_properties where property_name='DEFAULT_PERMANENT_TABLESPACE';

撤销表空间

   撤销表空间,一般存储、管理撤销数据。Oracle使用撤销数据来回退事务、提供数据的读一致性、帮助数据库从逻辑错误中恢复、实现闪回查询(Flashbackup Query)

   Oracle可以创建多个UNDO表空间,但是同时只能允许一个激活的UNDO表空间。

通过以下命令来查看正在使用的UNDO表空间

show parameter undo_tablespace;

通过以下命令来设置使用的UNDO表空间

alter system set undo_tablespace='UNDOTBS2' scope=both;

大文件表空间(BIGFILE)和小文件表空间(SMALLFILE)

   大文件表空间只能有一个数据文件(或临时文件)。数据文件可以包括4G个块,如果每个数据块设置为8KB,那么大文件表空间最大可以达到32TB(4*1024*1024*8KB)。

   小文件表空间可以拥有最多1022个数据文件。小文件可以包括4M个块,如果每个数据块设置为8KB,那么单个数据文件最大可达到32G(4*1024*1024*1024*8KB)。

表空间的状态

   处于不同模式的表空间,他的使用方式有所不同。通过人为改变表空间状态,可以控制表空间的可用性、安全性,也能为备份、恢复、迁移等工作提供准备和保证。

读写(read-write)

   默认情况下的表空间都是读写状态,任何具有权限的用户都可以对该表空间中的数据进行读写。

只读(read-only)

   设置为只读状态后,任何用户只能查询该表空间中的数据。设置为改状态一般都是历史数据只供查询使用。提高了数据库的安全性,在备份时只用备份一次就可以了。减少了DBA的管理负担。

脱机(offline)

   设置为脱机状态后,则代表该表空间的数据不让用户访问。一般用于数据库维护,数据文件损坏导致无法启动数据或者更改数据文件位置。如果脱机的表空间想恢复使用只需要在设置回联机即可。设置脱机有四种模式供选择

正常(normal)

   该模式是设置表空间脱机的默认模式,表空间以正常方式切换到脱机状态。使用该模式脱机后Oracle会自动执行checkpoint检查点将脏缓存写入到数据文件中,然后在关闭表空间的所有数据文件如果中间没发生任何错误,则可以进入normal脱机模式。所以下次联机不需要进行数据库恢复。(也就是说如果表空间或表空间的数据文件已经损坏则无法进入normal脱机模式)

临时(temporary)

   该模式让表空间以临时方式切换到脱机状态。该模式不需要所有数据文件都是联机的、可用的,但是Oracle会执行检查点。在执行检查点过程中因为数据文件处于不可用状态Oracle也会忽略这些错误进入temporary脱机模式。所以一般使用这个模式下次联机可能需要做数据库恢复。

立即(immediate)

   使用该脱机模式则属于强制进入脱机模式,不管数据文件是否联机、可用,也不会执行检查点直接进入脱机模式。所以下次联机必须要做数据库恢复。

用于恢复(for recovery)

   该脱机模式表示将表空间以恢复方式切换到脱机状态。一般用于对表空间进行基于时间的恢复。

注意:SYSTEM表空间不能设置为只读状态、脱机状态,因为数据库运行过程中始终会用到SYSTEM表空间。临时表空间也不能设置为制度状态。

表空间区、段的管理方式

区管理方式

区管理方式分为如下两种

   一、字典管理方式(dictionary-managed tablasepace,DMT)

       字典管理方式是传统管理方式,是为了与早期版本兼容而保留的区管理方式。字典管理方式是使用数据字典来管理存储空间的分配,就是说当表空间中分配新的区或者回收已分配区的时候,oracle都会对数据字典中的相关信息查询更新,速度较慢。

   二、本地管理方式(local-managed tablespace,LMT)

       本地管理方式是一种新方式,是一种新的改进的管理方式,Oracle强烈建议是用本地管理方式代替数据字典管理方式,并且在Oracle9i 以后默认使用的该管理方式。

       在本地管理方式下,表空间中区的分配与回收的管理都被存储在表空间的数据文件中,表空间在每个数据文件中维护一个“位图(bitmap)”结构,用于记录所有区的分配情况。(每个位图消耗64KB的表空间)

       在本地管理方式中还有两个选项来指定表空间的区的分配方式。

           统一(UNIFORM):统一分配,指定所有表空间的区大小相同,默认都是1M。不能对UNDO表空间使用该选项

           自动(AUTOALLOCATE或SYSTEM):自动分配,由Oracle系统来自动管理区的大小(默认)

               本地管理方式自动模式自动分配区大小与表的关系。当表大小不超过64KB时,表中每个分区大小为64K;当表的大小达到1MB时,表中区每个区的大小为1MB;当表的大小超过64MB小于1000MB时,区大小都是8M;当表数据大于1000MB时,系统在分配磁盘空间时一次分配64MB。

本地管理方式中段管理方式

   在本地管理方式的表空间中,除了可以使用UNIFORM或AUTOALLOCATE来指定区的分配方式,还可以指定段空间的管理方式。段空间管理方式主要是指Oracle用来管理段中已用数据块和空闲数据块的机制。段管理可以用下列两种方式来管理。

  MANUAL(手动):使用空闲列表(free list)来管理空闲的空闲数据块。该方式是为了与以前版本兼容而保留的

手工管理块

   pctfree:保留空余百分百(保留空余如果少于这个百分百,则认为已经不是可用块)

   pctused:允许使用百分比(如果里面数据超过这个百分比,则在free list中则记录它是已经使用完的,如果需要存数据会找下一个空余块。)

  AUTO(自动):使用位图(bitmap)来管理已用和空闲数据库。通过位图中单元的取值来判断数据块是否可用。

自动管理块:

   自动管理块的原理是,将一个块的空间分fs1、fs2、fs3、fs4四个状态,使用空间达到0%-25%、25%-50%、50%-75%、75%-100%时会打一个对应的标记,当空间已经使用到75%-100%时时会打上fs1状态,打上fs1状态的块在bitmap中该块就显示为已使用状态。如果块中有数据被删除,自动管理方式又会根据使用空间来确定是否需要重新定义状态,重新定义了标签,那么在bitmap中也会得到更新。

ps1:位图和空闲列表

   位图(bitmap):在数据文件中消耗64KB在每个段头来记录区或段是否使用,记录方式是为每个区或段保留一位。该位为1或0时来代表正在使用或空闲。

   空闲列表(free list):把段中所有的数据库都被放入到一个空闲列表中,当需要使用时在该列表中进行搜索。

ps2:段为什么要留空间

   段留空余空间主要是保留给update使用,在后续如果update数据时他就会将数据直接往空余块空间中插入。如果保留空间存储不下update的这一行数据时候这时候会产生行移动或者迁移,也就是说会把这一行数据一起迁移到一个能存储的下的块中。如果没有一个块能存储的下的话那么就会把这个行分片存储在两个或多个块当中这个又叫行链接。理论上来讲肯定是一行数据尽量存储在最少块中较好(也就是说一个块能搞定就不要用两个),因为这样在读写时是就只需要将一个块加载到内存中即可。如果多个块就增加了磁盘I/O,也增加了内存的开销。原理来说肯定是一个块里面数据来的快。

   不管是移动行或者行链接他的rowid是不会变的,所以在访问该移动或链接的行都会访问原来的块,然后通过原来块中的rowid链接指到存储数据所在块。所以会产生两次读块的I/O过程。但是在后续使用中如果rowid所在块中通过整理碎片或者有数据删除后剩余空间能存放的下已经迁移出去的行的数据时,它会在迁移回来。

延迟段

   在11.2之前建表时候立马就会分配一个段(也就是段的第一个区间),也就是说在建表的时候,在数据字典中添加信息之后,立马给该表在表空间中分配一个段。在11.2之后出现了延迟分配段这个功能(deferred_segment_creation = true 默认开启),就是在建表的时候只更新数据字典信息不分配段,等实际插入信息时在分配段。如果表使用延迟创建段那么该表的索引段也会延迟创建。

   延迟段只能用作于以下三种:一、非分区表、非分区索引;二、IOTs 索引组织表、CLUSTER 表、其它的特殊表;三、本地管理表空间中的表

   如果你要把本地管理表空间中使用了延迟表的表移动到,数据字典管理的表空间中,你需要将该表删除在重建。

   延迟段的好处

       索引失效后释放段空间,但是数据继续保留,在rebuild之后又能恢复所有信息,使用

           创建索引,指定让它失效:create index test_i1 on zhanky.cs(l1) unusable;

           更改索引状态为失败:alter index test_i unusable;

           重建索引:alter index test_i rebuild;

段区管理常用命令

使用该命令查看是否开启延迟分配段:

show parameter deferred_segment_creation

建表时指定延迟分配段:

create table zhanky.d (l1 number,l2 number) segment creation immediate;

建表时指定参数立马分配段:

create table zhanky.c (l1 number,l2 number)

segment creation deferred;

查询段信息:

select * from dba_segments where segment_name='CS';

查询区间信息:

select * from  dba_extents where segment_name='CS';

整理段

先回收数据,不回收HWM。(整理碎片空间,系统的删除插入让碎片空间快填满)

alter table 表名 shrink space compact;

回收HWM。(业务少的时候弄)

alter table 表名 shrink space;

HWM:添加数据时,最后一个块的块号

整理段好处:提高性能、提高利用率、减少行链接行移动、索引自动重建

管理表空间的准则

确认表空间的大小

   确定表空间的大小一般根据表空间中所有表的大小来确定。下面来介绍确认表的大小和表空间的大小。

   确定表的大小

       我们通过查询视图USER_TAB_COLUMNS来得知以下参数

       表的大小=最大行长*行数*(1+PCTFREE/100)*预留百分比

       

   确定表空间的大小:通过表空间下所有表的估值大小来做初始大小,后续观察监视使用情况增长情况在调整。

表压缩

   表压缩,实现在插入时就压缩存储到数据库上,(对系统几乎无影响,只会小号很小的CPU)。在建表时指定语句确定表是否开启压缩技术。压缩主要分为两种(BASIC、OLTP),Oracle的压缩在读取时是可以直接读取的,不需要解压缩。减少了块的使用,其实也是减少了I/O增加了数据库的效率也减少了存储的空间。

   如果建的表需要压缩时只需要在创建时增加命令即可:{COMPRESS [ BASIC | FOR { OLTP } ] | NOCOMPRESS },如果不指定默认是NOCOMPRESS 不压缩。

BASIC:压缩比例可达到十倍,但是该方式只支持数据仓库系统,在建表时加COMPRESS BASIC。在老版本中使用命令COMPRESS FOR DIRECT_LOADOPERATIONS。支持(DSS),只支持批量装载数据压缩。

BASIC压缩原理:当写入数据到块的时候还不会压缩,当一个块达到PCTFREE时就开始压缩,压缩完了继续往里面插入数据,当达到PCTFREE时在压缩。当使用BASIC时PCTFREE默认就变成0了。

OLTP:压缩比例可达到二至四倍COMPRESS FOR OLTP,老版本中是使用命令COMPRESS FOR ALL OPERATIONS。支持(OLTP、DSS)

OLTP压缩原:在写入到块中时对该块内部数据进行运算,对重复值压缩来较少空间的占用。

11.2.0以后有compression advisor(压缩专家)工具DBMS_COMPRSSION

表压缩测试命令

查看表是否开启压缩

select t.table_name,t.compression,t.compress_for from  dba_tables t where tbale_name='cs';

创建OLTP压缩表

create table zhanky.csa compress for oltp as (select * from zhanky.cs where 1=2);

插入数据(大概一百万条)

insert into zhanky.csa (select * from zhanky.cs)

查看块使用情况

select t.BYTES,t.blocks,t.blocks*8/1024/1024 from dba_segments t where t.segment_name='CSA';
select t.BYTES,t.blocks,t.blocks*8/1024/1024 from dba_segments t where t.segment_name='CS';

如果查询没找到块的使用情况,执行一下表分析

analyze table zhanky.csa compute statistics;

表空间的配置

   表空间的配置实质性考虑如何创建层次结构的表空间(以便将表创建在相对应的表空间中,减少竞争),以及将表空间中的数据文件安排放在哪个磁盘中。

  • 将用户数据和数据字典数据分别存放,避免数据字典对象和方案对象被保存在同一个数据文件中而产生I/O冲突。

  • 将一个应用程序的数据与另个应用程序的数据分别存放, 保证各个应用程序的数据的独立性,防止如果一个表空间必须被脱机,则多个应用程序都受到影响的情况。

  • 在不同的磁盘驱动器上存储不同表空间的数据文件,以减少I/O竞争,平均分配I/O操作。

  • 将撤销数据与用户数据分别存放,防止单个磁盘的故障造成数据的永久丢失。

  • 当其他表空间保持联机时,可以使某个表空间脱机,以便对数据库的一部分 进行单独的备份恢复,提供更好的整体可用性。

  • 能够将某个表空间设置为只读状态,从而将数据库的一部分设置为只读状态。

  • 能够为某种特殊用途专门设置一个表空间,比如临时表空间、撤销表空间等,以优化表空间的使用效率,如快速更新动作、只读动作。

  • 能够更加灵活地为用户设置表空间配额。

  • 某些操作系统对一个进程 可以同时打开的文件数进行了限制。这些限制会影响同时联机的表空间数量。因此,为避免超过操作系统的限制,在建立数据库时,DBA应当仔细地规划所需表空间的数量,尽量做到为不同类型的应用创建独立的表空间,并且只创建满足需求的足够的表空间。

  • 在创建表空间时,应当为表空间创建几个较大的数据文件或者将数据文件设置为自动增长方式,而不要为表空间创建许多很小的数据文件。