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 等视图来盘点实际文件,而不能靠目录约定去推断。
各层对象对容量规划的实际影响
把层次理清后,容量规划就有了明确的“计算锚点”。下面按对象说明它们各自影响什么。
| 对象 | 容量规划中的关键作用 | 常用观察视图 |
|---|---|---|
| 块 | 决定单块行数与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 与数据文件可扩展空间做交叉验证:只有当“数据文件还能长”且“磁盘组还有余量”同时成立时,表空间才真正具备扩容能力。
DBA_DATA_FILES 和 V$ASM_FILE 等视图盘点,避免遗漏或重复计算。总结来看,Oracle存储对象从块、区、段、表空间到数据文件、ASM磁盘组,是一条自下而上的容量归属链。块和区决定“怎么分”,段决定“谁在用”,表空间和数据文件决定“能长多大”,ASM磁盘组决定“物理上还剩多少”。容量规划的正确做法,是沿着这条链逐层核对,而不是只看某一个视图的数字。