2. Oracle存储架构与容量对象

做Oracle容量规划,第一步不是算磁盘大小,而是把“容量到底落在哪些对象上”这件事理清楚。Oracle的存储是一套严格的分层结构:最底层是操作系统或ASM提供的物理存储,向上依次是数据文件、表空间、段、区、块。容量规划之所以容易出错,往往是因为只盯着表空间使用率,却忽略了段和区在表空间内部的分配方式,以及ASM磁盘组这一层的冗余开销。

从块到表空间:自下而上的层次

块(Block)是Oracle I/O的最小单位,由初始化参数 DB_BLOCK_SIZE 决定,常见为8KB,创建数据库后不可更改。块的大小直接影响单行能容纳的数据量、行迁移概率以及全表扫描的I/O次数。容量估算时,块大小决定了“一个块能装多少行”,进而决定表需要多少个块。

区(Extent)是连续块的集合,是Oracle分配空间的基本单位。一个段至少包含一个区。区的大小由表空间的分配方式决定:字典管理已淘汰,现在普遍使用本地管理表空间(LMT),可选择自动分配(AUTOALLOCATE)或统一区大小(UNIFORM SIZE)。AUTOALLOCATE下区大小从64KB起步逐步翻倍到64MB,适合区大小难以预估的混合负载;UNIFORM SIZE则让每个区大小固定,适合可预测的大表或分区表,能减少碎片。

段(Segment)是占用存储的逻辑对象,一张非分区表对应一个表段,一个索引对应一个索引段,还有回滚段、临时段、LOB段等。段是容量规划真正要“数”的对象——表空间使用量本质上是其中所有段占用区之和。段可以分布在多个数据文件上,但一个区必须完整位于同一个数据文件中。

表空间(Tablespace)是段的逻辑容器,一个表空间由一个或多个数据文件组成。SYSTEM、SYSAUX、UNDO、TEMP是必需的系统表空间,业务数据通常放在自定义表空间中。表空间是容量监控和配额管理的主要抓手,但要注意:表空间“剩余空间”是数据文件可用空间之和,而数据文件可以自动扩展(AUTOEXTEND),所以表空间使用率并不等于物理磁盘的真实余量。

数据文件(Data File)是表空间在操作系统层面的物理载体,对应一个具体路径的文件。数据文件的大小、是否自动扩展、每次扩展多少、最大能到多大,直接决定表空间能长到多大。规划时必须同时看数据文件当前大小、MAXBYTES和磁盘剩余空间三者中的最小值。

ASM磁盘组与OMF

如果使用ASM(Automatic Storage Management),数据文件并不直接落在文件系统上,而是放在ASM磁盘组中。磁盘组由若干ASM磁盘组成,通过冗余级别决定可用容量:EXTERNAL不做镜像,可用容量约等于裸容量;NORMAL做双路镜像,可用容量约为裸容量的一半;HIGH做三路镜像,可用容量约为裸容量的三分之一。这是容量规划中最容易被低估的一环——申请了10TB裸盘,NORMAL冗余下实际可用只有约5TB。

OMF(Oracle Managed Files)让Oracle自动管理文件的命名和存放位置。启用OMF后,创建表空间时只需指定大小,Oracle会按 DB_CREATE_FILE_DEST 自动生成文件名并放置。OMF简化了管理,但也意味着文件路径不再由DBA手工控制,容量规划时要依赖 V$DATAFILE、DBA_DATA_FILES 等视图来盘点实际文件,而不能靠目录约定去推断。

Oracle存储对象层次与容量归属 物理存储层 文件系统 / 裸设备 ASM 磁盘组(冗余决定可用量) EXTERNAL / NORMAL / HIGH 数据文件层(Data File) 大小 / AUTOEXTEND / MAXBYTES OMF 自动命名与落盘 一个区不跨数据文件 表空间层(Tablespace) SYSTEM / SYSAUX UNDO / TEMP 业务表空间(配额管理) 本地管理 LMT 段层(Segment) 表段 / 索引段 LOB 段 / 回滚段 临时段 段 = 区之和 区(Extent) 连续块集合,分配基本单位 AUTOALLOCATE 或 UNIFORM SIZE 块(Block) I/O 最小单位,DB_BLOCK_SIZE 常见 8KB,建库后不可改

各层对象对容量规划的实际影响

把层次理清后,容量规划就有了明确的“计算锚点”。下面按对象说明它们各自影响什么。

对象容量规划中的关键作用常用观察视图
块决定单块行数与I/O效率,影响表所需块数估算DB_BLOCK_SIZE
区决定空间分配粒度,影响碎片与浪费DBA_TABLESPACES
段真正占用空间的实体,是增长预测的对象DBA_SEGMENTS
表空间配额与监控抓手,不等于物理余量DBA_TABLESPACE_USAGE_METRICS
数据文件决定表空间上限,受MAXBYTES与磁盘限制DBA_DATA_FILES
ASM磁盘组冗余级别决定可用容量,是物理容量换算关键V$ASM_DISKGROUP

一个可复用的容量盘点示例

假设某业务库使用ASM,NORMAL冗余,磁盘组裸容量20TB,则可用容量约10TB。业务表空间 APP_DATA 当前由两个数据文件组成,各32GB,均开启AUTOEXTEND,每次扩展1GB,MAXBYTES为32GB(即已到上限)。此时表空间实际可增长空间为0,即使磁盘组还有余量也无法扩展。要扩容,必须先把MAXBYTES调大或新增数据文件。

-- 查看表空间使用与数据文件上限
SELECT tablespace_name, bytes/1024/1024 mb, maxbytes/1024/1024 max_mb,
       autoextensible
FROM   dba_data_files
WHERE  tablespace_name = 'APP_DATA';

-- 查看段占用,定位增长最快的对象
SELECT owner, segment_name, segment_type,
       bytes/1024/1024 mb
FROM   dba_segments
WHERE  tablespace_name = 'APP_DATA'
ORDER  BY bytes DESC
FETCH FIRST 10 ROWS ONLY;

-- 查看ASM磁盘组可用容量
SELECT name, total_mb/1024 total_gb,
       free_mb/1024 free_gb, type
FROM   v$asm_diskgroup;

执行后如果发现 DBA_SEGMENTS 中某张表或某个LOB段占了绝大部分空间,容量规划的重点就应放在该对象的增长趋势上,而不是平均分摊到所有表。同时用 V$ASM_DISKGROUP 的 free_gb 与数据文件可扩展空间做交叉验证:只有当“数据文件还能长”且“磁盘组还有余量”同时成立时,表空间才真正具备扩容能力。

容量规划中一个常见误区:把表空间使用率当作磁盘使用率。表空间使用率只反映段已占用的区,而数据文件可能预留了大量未使用空间,ASM磁盘组又可能因镜像而只剩一半可用。三者必须分别核算。
使用OMF时,数据文件路径由Oracle自动生成,不要依赖固定目录去统计容量。应统一通过 DBA_DATA_FILES 和 V$ASM_FILE 等视图盘点,避免遗漏或重复计算。

总结来看,Oracle存储对象从块、区、段、表空间到数据文件、ASM磁盘组,是一条自下而上的容量归属链。块和区决定“怎么分”,段决定“谁在用”,表空间和数据文件决定“能长多大”,ASM磁盘组决定“物理上还剩多少”。容量规划的正确做法,是沿着这条链逐层核对,而不是只看某一个视图的数字。