最近一直想分清楚oracle的表空间与数据文件的关系,查了好些材料,最后想了下整理下,写了这篇关于Oracle存储结构的blog【资料大部分来自网络】。
Oracle的存储分为两部分(1):逻辑存储部分,从大到下为,database、tablespace、segment、extent、data block。(2):物理存储部分包含,data file、os block。整个的存储架构如下图。
从逻辑的角度来看,一个数据库(database)下面可以分多个表空间(tablespace);一个表空间下面又可以分多个段(segment);一个数据表要占一个段(segment),一个索引也要占一个段(segment )。 一个段(segment)由多个 区间(extent)组成,那么一个区间又由一组连续的数据块(data block)组成。这连续的数据块是在逻辑上是连续的,有可能在物理磁盘上是分散。
那么从物理的角度上看,一个表空间由多个数据文件组成,数据文件是实实在在存在的磁盘上的文件。这些文件是由操作系统的block 组成的。
1:tablespace【表空间】
表空间是最高一级的逻辑存储结构,通过表空间oracle就可以将相关的逻辑结构和对象组合在一起,oracle就是由若干个表空间组成。段就包含在表空间中。一个表空间包含多个数据文件,一个数据文件只能属于一个表空间,建立一个表空间的时候,是需要指定存储的文件。一个表空间可以指定多个数据文件,多个文件可以在不同的物理存储上。也就是说,表空间是可以跨物理存储的。但是有一点就是,表空间下一级对象数据段的存储,是不能指定存储在那个文件里的。所以,要想让数据对象访问IO负载均衡,需要指定不同的数据段。
Oracle表空间之作用
表空间的作用能帮助DBA用户完成以下工作:
1.决定数据库实体的空间分配;
2.设置数据库用户的空间份额;
3.控制数据库部分数据的可用性;
4.分布数据于不同的设备之间以改善性能;
5.备份和恢复数据。
用户创建其数据库实体时其必须于给定的表空间中具有相应的权力,所以对一个用户来说,其要操纵一个ORACLE数据库中的数据,应该:
1.授予关于一个或多个表空间中的RESOURCE特权;
2.指定缺省表空间;
3.分配指定表空间的存储空间使用份额;
4.指定缺省临时段表空间。
Oracle可以创建的表空间有三种类型:
(1)TEMPORARY: 临时表空间【用于排序的空间,当需要对数据进行排序时,如果内存排序区域不够大不能满足排序要求,就在该区域中进行排序;能引起排序的操作有:order by,group by,distinct,sort merge join,create index,union;TEMP表空间还是temporary table 的使用空间;】,用于临时数据的存放;创建临时表空间的语法如下:CREATE TEMPORARY TABLESPACE "SAMPLE"。。。。。。
(2)UNDO : 还原表空间【用于保存用户DML操作前数据,以备用户反悔ROLLBAK,以前在COMMIT之前其他用户依然能访问修改前的数据,保持数据的一致性】。用于存入重做日志文件。创建还原表空间的语法如下:CREATE UNDOTABLESPACE "SAMPLE"。。。。。。
(3)用户表空间: 最重要,也是用于存放用户数据表空间可以直接写成: CREATE TABLESPACE"SAMPLE"TEMPORARY 和 UNDO 表空间是Oracle 管理的特殊的表空间。只用于存放系统相关数据。
SQL> desc v$tablespace; Name Type Nullable Default Comments --------------------------- ------------ -------- ------- -------- TS# NUMBER Y NAME VARCHAR2(30) Y INCLUDED_IN_DATABASE_BACKUP VARCHAR2(3) Y BIGFILE VARCHAR2(3) Y FLASHBACK_ON VARCHAR2(3) Y ENCRYPT_IN_BACKUP VARCHAR2(3) Y
2:segment【段】
段由多个区组成。这些区可以是连续的,也可以是不连续的。当用户在数据库中创建各种具有实际存储结构的对象时oracle就将为这些实际对象(表、索引…)创建段,这些对象将全部保存在其段中,一般情况下一个对象只会有一个段,一个表或索引对应一个SEGMENT,一个SEGMENT可以跨多个数据文件。
简单的说oracle里的段有4种类型:
a.数据段:存放数据的段,oracle中所有未分区的表都使用一个段来保存数据,而分区的表将为每个分区建立一个独立的数据段。
b.索引段:存放索引条目的段,oracle中所有未分区的索引都使用一个段来保存数据,而分区的索引将为每个分区建立一个独立的数据段。
c.临时段:放临时数据的段。最好不要在SYSTEM表空间中存放临时段,以避免产生碎片。
d.回退段:保存回退条目,oracle将被修改的数据的初始化版本保存在回退条目中,利用这些信息,用户可使用撤销未提交的事务的方式来恢复崩溃的实例,也就是roll back啦。当然关于回退段展开讲的话可能会很深,这里就不多说了。而且回退段的概念在以后的oracle版本中可能会弃用。
有一个问题需要注意,通常我们的数据段是与数据对象相关。一个数据对象对应一个segment。但是,分区表的时候,一个分区要对应一个segment对象。还有就是,segment对象是可以指定存储在那个表空间里,实现存储划分的基础也就在于此。不同类型的segment划分建立在不同的表空间里,才有可能存放在不同的文件中,最后分布在不同的物理存储。分区实际上就是存在分开存储的可能。一般一个对象是不会跨物理存储进行存放的。
相关的数据视图请参考dba_segments【使用dba用户】,视图描述段总共包含"TABLE", "CLUSTER", "INDEX", "ROLLBACK","DEFERRED ROLLBACK", "TEMPORARY","SPACE HEADER", "TYPE2 UNDO"。
SQL> desc dba_segments; Name Type Nullable Default Comments --------------- ------------ -------- ------- -------------------------------------------------------------------------------------------------------------------------------------- OWNER VARCHAR2(30) Y Username of the segment owner SEGMENT_NAME VARCHAR2(81) Y Name, if any, of the segment PARTITION_NAME VARCHAR2(30) Y Partition/Subpartition Name, if any, of the segment SEGMENT_TYPE VARCHAR2(18) Y Type of segment: "TABLE", "CLUSTER", "INDEX", "ROLLBACK", "DEFERRED ROLLBACK", "TEMPORARY","SPACE HEADER", "TYPE2 UNDO" or "CACHE" TABLESPACE_NAME VARCHAR2(30) Y Name of the tablespace containing the segment HEADER_FILE NUMBER Y ID of the file containing the segment header HEADER_BLOCK NUMBER Y ID of the block containing the segment header BYTES NUMBER Y Size, in bytes, of the segment BLOCKS NUMBER Y Size, in Oracle blocks, of the segment EXTENTS NUMBER Y Number of extents allocated to the segment INITIAL_EXTENT NUMBER Y Size, in bytes, of the initial extent of the segment NEXT_EXTENT NUMBER Y Size, in bytes, of the next extent to be allocated to the segment MIN_EXTENTS NUMBER Y Minimum number of extents allowed in the segment MAX_EXTENTS NUMBER Y Maximum number of extents allowed in the segment PCT_INCREASE NUMBER Y Percent by which to increase the size of the next extent to be allocated FREELISTS NUMBER Y Number of process freelists allocated in this segment FREELIST_GROUPS NUMBER Y Number of freelist groups allocated in this segment RELATIVE_FNO NUMBER Y Relative number of the file containing the segment header BUFFER_POOL VARCHAR2(7) Y The default buffer pool to be used for segments blocks
3:extent【区】
区extent是比数据块大一级的存储结构,区是由多个物理上连续的Oracle块组成的,是Oracle存储分配的最小单位,是一连串连续的数据块集合,一个EXTENT只能在一个数据文件中;区间也叫扩展,因为当它用完已经分配的区间后,再有新的记录插入就必须在分配新的区间(即扩展一些块);一旦区间分配给某个对象(表、索引及簇),则该区间就不能再分配给其它的对象.。我们知道,物理存储通常是随机的读写过程。即使在同一个文件里,我们也不能保证相同的一个信息是存储在绝对连续的物理存储空间的。Oracle数据存储同样如此。
在进行存储数据信息的时候,Oracle将分配数据块进行存储,但是不能保证所有分配的数据块都是连续的结构。所以,出现分区extent的概念,表示一系列连续的数据块集合。
视图dba_extents(或者all_extents、user_extents)是我们研究分区结构和存储构成的重要手段。
SQL> desc dba_extents; Name Type Nullable Default Comments --------------- ------------ -------- ------- --------------------------------------------------------- OWNER VARCHAR2(30) Y Owner of the segment associated with the extent SEGMENT_NAME VARCHAR2(81) Y Name of the segment associated with the extent PARTITION_NAME VARCHAR2(30) Y Partition/Subpartition Name, if any, of the segment SEGMENT_TYPE VARCHAR2(18) Y Type of the segment TABLESPACE_NAME VARCHAR2(30) Y Name of the tablespace containing the extent EXTENT_ID NUMBER Y Extent number in the segment FILE_ID NUMBER Y Name of the file containing the extent BLOCK_ID NUMBER Y Starting block number of the extent BYTES NUMBER Y Size of the extent in bytes BLOCKS NUMBER Y Size of the extent in ORACLE blocks RELATIVE_FNO NUMBER Y Relative number of the file containing the segment header
从视图中,我们可以清晰看出分区的几个特点。首先分区是带有段特定性的。数据段segment是分区的上层组织单位,一个数据库对象对应一个segement,数据库对象是归属在不同的schema(owner)上的。所以,通过不同的数据段名称、不同的owner,乃至不同的tablespace表空间信息,就可以定位到数据区extent的信息描述。
另一部分信息是关于该区extent的分配信息,如所在文件编号,起始数据块block编号和数据块数量等内容。
4:Block【数据块】
数据块Block是Oracle存储数据信息的最小单位,是Oracle一次I/O的基本单位,它是OS块的整数倍,块的IO次数多少对性能至关重要,一个数据块对应于磁盘上特定数量的物理数据库空间。注意,这里说的是Oracle环境下的最小单位。Oracle也就是通过数据块来屏蔽不同操作系统存储结构的差异。无论是Windows环境,还是Unix/Linux环境,他们的操作系统存储结构和方式、甚至字符排列的方式都是不同的。Oracle利用数据块将这些差异加以屏蔽,全部数据操作采用对Oracle块的操作,相当于是一个层次的抽象。
Oracle所有对数据的操作和空间分配,实际上都是针对数据块Block的操作。我们从数据表中搜索出一行,实际中Oracle就会从内存缓冲区(或者硬盘)中读取到该行所在的数据块,再返回这数据块上的指定数据行。Oracle无论是在缓冲区,还是在硬盘,进行数据操作的虽小单位也就是数据块。
数据块是有大小的,在一个数据库建立的时候,通过参数进行设置。注意,在Oracle数据库参数中,只有数据块大小的参数是建库之后不能进行修改的。数据块的大小,在一个数据库中可以支持多个,但是一般没有太大的意义,会给管理和调试带来一定的负担。
数据块的大小是通过kb字节个数来指定的,默认为8KB。相关参数为db_block_size,下面是查看block大小的语句。
SQL> show parameter db_block_size; NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ db_block_size integer 8192
设置数据块的大小是依据不同类型的系统的。如果数据块设置比较大,那么一次读取的数据行较多,相应对SGA内存消耗比较大,特定查询引发的换入换出可能较多。如果设置的过小,频繁的IO逻辑物理读也会引起性能问题。
与数据块有关系的另一个参数就是db_file_multiblock_read_count,表示一次从物理存储中读取的数据块数量。对一些数据挖掘系统,可以考虑调节此参数略大一些。
5:数据文件(data file)
一个数据库可以由多个数据文件组成的,数据文件是真正存放数据库数据的.一个数据文件就是一个操作系统文件.数据库的对象(表和索引)物理上是被存放在数据文件中的.
数据文件的特征是:
A:一个数据文件只能属于一个数据库.
B:数据文件可以被设置成自动增长.
C:一个或多个数据文件组成了表空间.
D:一个数据文件只能属于一个表空间.
当我们要查询一个表的数据的时候,如果该表的数据没有在内存中,那么oracle就要读取该表所在的数据文件,然后把数据存放的内存中。
SQL> desc dba_data_files; Name Type Nullable Default Comments --------------- ------------- -------- ------- --------------------------------------------------- FILE_NAME VARCHAR2(513) Y Name of the database data file FILE_ID NUMBER Y ID of the database data file TABLESPACE_NAME VARCHAR2(30) Y Name of the tablespace to which the file belongs BYTES NUMBER Y Size of the file in bytes BLOCKS NUMBER Y Size of the file in ORACLE blocks STATUS VARCHAR2(9) Y File status: "INVALID" or "AVAILABLE" RELATIVE_FNO NUMBER Y Tablespace-relative file number AUTOEXTENSIBLE VARCHAR2(3) Y Autoextensible indicator: "YES" or "NO" MAXBYTES NUMBER Y Maximum size of the file in bytes MAXBLOCKS NUMBER Y Maximum size of the file in ORACLE blocks INCREMENT_BY NUMBER Y Default increment for autoextension USER_BYTES NUMBER Y Size of the useful portion of file in bytes USER_BLOCKS NUMBER Y Size of the useful portion of file in ORACLE blocks ONLINE_STATUS VARCHAR2(7) Y Online status of the file