Oracle 数据文件与表空间架构详解

Oracle 数据文件与表空间架构详解

适用版本:Oracle Database 19c / 23ai 阅读基础:了解 Oracle 物理结构和逻辑结构 文档版本:v1.0 / 2026-07


目录


1. 概述:Oracle 存储的分层架构

Oracle 数据库采用逻辑 + 物理分层存储架构[1][2]:

逻辑存储结构                  物理存储结构
─────────────                ─────────────
Database                     数据库
  ↓                            ↓
Tablespace(表空间)    ←→   Datafile(数据文件)
  ↓                            ↓
Segment(段)                 (在数据文件中)

Extent(区)

Data Block(数据块)

层级关系[1][2]:

  • 一个数据库有多个表空间
  • 一个表空间对应一个或多个数据文件
  • 一个段跨多个区
  • 一个区在单个数据文件内连续
  • 一个数据块是最小 I/O 单位

类比

层级类比
表空间书架
数据文件书架的隔层
一本书
一章
数据块一页纸

2. 物理结构:数据文件

数据文件(Datafile)是 Oracle 在操作系统层面的物理文件[1]。

核心特点

  • 只能属于一个表空间
  • 一个表空间可包含多个数据文件
  • 二进制文件,不能用文本编辑器查看
  • 大小可固定或自动扩展
  • 包含数据块和文件头

文件头内容

  • 数据文件号
  • 所属表空间
  • 检查点 SCN
  • 重置日志 SCN
  • 创建时间戳

查看数据文件

SELECT file_name, file_id, tablespace_name, 
       bytes/1024/1024 AS size_mb,
       status, autoextensible, 
       maxbytes/1024/1024 AS max_mb,
       increment_by
FROM dba_data_files
ORDER BY tablespace_name, file_id;

3. 逻辑结构:表空间、段、区、块

3.1 表空间(Tablespace)

表空间是最大的逻辑存储单位[1][2]。

核心特点

  • 一个数据库至少有 SYSTEM、SYSAUX、TEMP、UNDOTBS 几个表空间
  • 包含一个或多个数据文件
  • 段不能跨表空间
  • 区可以跨数据文件(同一表空间内)

表空间类型

类型说明
Permanent永久表空间(SYSTEM, USERS 等)
UndoUndo 表空间
Temporary临时表空间(TEMP)

3.2 段(Segment)

段是数据库对象占用的存储空间[1][2]。

段类型

段类型说明
TABLE表段
INDEX索引段
CLUSTER簇段
TABLE PARTITION表分区段
INDEX PARTITION索引分区段
LOBSEGMENTLOB 数据段
LOBINDEXLOB 索引段
ROLLBACK回滚段
TEMPORARY临时段
NESTED TABLE嵌套表段

查看段

SELECT segment_name, segment_type, tablespace_name, 
       bytes/1024/1024 AS size_mb, extents, blocks
FROM dba_segments
WHERE owner = 'SCOTT'
ORDER BY bytes DESC;

3.3 区(Extent)

区是 Oracle 为段分配空间的最小单位[1][2],由连续的数据块组成。

核心特点

  • 连续性:区内的块在数据文件中物理连续
  • 按需分配:段空间用完时自动分配新区
  • 大小可变:初始区、后续区可不同大小

查看区分配

SELECT segment_name, segment_type, 
       extent_id, file_id, block_id, 
       blocks, bytes/1024 AS size_kb
FROM dba_extents
WHERE owner = 'SCOTT' AND segment_name = 'EMP'
ORDER BY extent_id;

区分配策略(LMT UNIFORM):

CREATE TABLESPACE users
DATAFILE '/u01/oradata/orcl/users01.dbf' SIZE 100M
EXTENT MANAGEMENT LOCAL UNIFORM SIZE 1M;
-- 每个区固定 1MB

区分配策略(LMT AUTOALLOCATE,默认):

CREATE TABLESPACE users
DATAFILE '/u01/oradata/orcl/users01.dbf' SIZE 100M
EXTENT MANAGEMENT LOCAL AUTOALLOCATE;
-- Oracle 自动决定区大小(64K、1M、8M、64M)

3.4 数据块(Data Block)

数据块是 Oracle 最小的存储和 I/O 单位[1][2]。

核心参数

参数说明典型值
DB_BLOCK_SIZE标准块大小8KB(OLTP)/ 32KB(OLAP)
块头块地址、类型、事务信息约 100 字节
表目录块中数据的表信息动态
行目录行的偏移地址动态
空闲空间可用于插入或更新动态
行数据实际数据主体

查看块大小

SHOW PARAMETER db_block_size

-- 查看非标准块大小
SELECT tablespace_name, block_size 
FROM dba_tablespaces;

坑 1:块大小在数据库创建后不能修改,需要重建数据库。


4. 数据块内部结构

数据块的物理结构[1]:

┌──────────────────────────────────┐
│ Block Header(块头)              │
│  - 块地址                         │
│  - 段类型                         │
│  - 事务表(ITL,Interested Transaction List)│
│  - SCN                            │
├──────────────────────────────────┤
│ Table Directory(表目录)         │
│  - 该块包含的表信息                │
├──────────────────────────────────┤
│ Row Directory(行目录)           │
│  - 每行的偏移地址                  │
├──────────────────────────────────┤
│ Free Space(空闲空间)            │
│  - 用于插入和更新                  │
├──────────────────────────────────┤
│ Row Data(行数据)                │
│  - 实际表数据                      │
└──────────────────────────────────┘

ITL(事务槽)

  • 每个块头部有事务表
  • 记录当前修改该块的事务
  • 默认 2 个槽,可通过 INITRANS 调整
  • 满时会扩展到 MAXTRANS

PCTFREE 和 PCTUSED[1]:

参数说明默认
PCTFREE预留空间百分比,用于更新10
PCTUSED块使用率低于此值时允许插入40
块空间使用:
  ┌── 0% ──── PCTUSED ──── (100-PCTFREE)% ──── 100% ──┐
  │   空闲     可插入区        仅更新区       │
  │  (不可插入)            (已满不可插入)    │
  └─────────────────────────────────────┘

  插入过程:空闲 → (100-PCTFREE)% → 停止插入
  删除过程:(100-PCTFREE)% → PCTUSED → 允许再次插入

5. 表空间类型

类型用途示例
Permanent永久存储业务数据SYSTEM, SYSAUX, USERS
Undo存储 Undo 数据UNDOTBS1
Temporary临时数据(排序、哈希)TEMP
Bigfile单文件大表空间用户创建
Encrypted加密表空间安全场景

6. 表空间管理方式

6.1 区管理:DMT vs LMT

字典管理表空间(DMT,Dictionary-Managed Tablespace)[2]:

  • 依赖数据字典表(UET$, FET$)记录区信息
  • 分配/回收区需修改数据字典
  • 易产生锁等待
  • 易产生碎片
  • 已废弃

本地管理表空间(LMT,Locally-Managed Tablespace)[2]:

  • 依赖数据文件头的位图记录区信息
  • 位图直接标记区状态
  • 无字典争用,效率高
  • 无外部碎片
  • Oracle 10g+ 默认

查看区管理模式

SELECT tablespace_name, extent_management, allocation_type 
FROM dba_tablespaces;
-- EXTENT_MANAGEMENT: LOCAL(推荐)/ DICTIONARY(已废弃)

创建 LMT

CREATE TABLESPACE users 
DATAFILE '/u01/oradata/orcl/users01.dbf' SIZE 100M
EXTENT MANAGEMENT LOCAL UNIFORM SIZE 1M;

6.2 段管理:MSSM vs ASSM

手动段空间管理(MSSM)[2]:

  • 依赖**空闲列表(Free List)**跟踪空闲块
  • 需手动设置 PCTFREEPCTUSED
  • 高并发场景下空闲列表竞争
  • 易产生碎片

自动段空间管理(ASSM)[2]:

  • 依赖位图跟踪块状态(空闲、半满、全满)
  • 自动管理块分配
  • 无需 PCTUSED(PCTFREE 仍生效)
  • 支持高并发
  • 支持 Segment Shrink
  • Oracle 10g+ 默认

查看段管理模式

SELECT tablespace_name, segment_space_management 
FROM dba_tablespaces;
-- SEGMENT_SPACE_MANAGEMENT: AUTO(推荐)/ MANUAL

创建 ASSM

CREATE TABLESPACE app_data 
DATAFILE '/u01/oradata/orcl/app_data01.dbf' SIZE 200M
EXTENT MANAGEMENT LOCAL
SEGMENT SPACE MANAGEMENT AUTO;

7. 标准表空间

7.1 SYSTEM 表空间

  • 存储数据字典(SYS 用户的表、视图)
  • 包含所有 PL/SQL 存储过程源码
  • 不可删除、不可脱机、不可只读
  • 不要存放业务数据
SELECT file_name, bytes/1024/1024 AS size_mb
FROM dba_data_files
WHERE tablespace_name = 'SYSTEM';

7.2 SYSAUX 表空间

  • 10g 引入,作为 SYSTEM 的辅助
  • 存储 AWR、EM、Text、Spatial 等组件
  • 不可删除,但可脱机
-- 查看 SYSAUX 占用者
SELECT occupant_name, space_usage_kbytes/1024 AS size_mb
FROM v$sysaux_occupants
ORDER BY space_usage_kbytes DESC;

7.3 UNDO 表空间

7.4 TEMP 表空间

  • 存储 SQL 排序、哈希连接的临时数据
  • 至少一个
  • 共享给所有用户使用
SELECT file_name, bytes/1024/1024 AS size_mb
FROM dba_temp_files;

-- 查看临时段使用情况
SELECT tablespace_name, 
       SUM(bytes_used)/1024/1024 AS used_mb,
       SUM(bytes_free)/1024/1024 AS free_mb
FROM v$temp_space_header
GROUP BY tablespace_name;

7.5 USERS 表空间

  • 默认用户表空间
  • 创建用户时如未指定,使用此表空间
  • 生产环境建议为每个业务创建独立表空间

8. 大文件表空间(Bigfile Tablespace)

10g 引入[1],单个数据文件最大可达 4G × block_size(8K 块即 32TB)。

特点

  • 单文件,简化管理
  • 减少 Latch 争用
  • 必须用 ASM 或 LMT + ASSM

创建

CREATE BIGFILE TABLESPACE big_data
DATAFILE '/u01/oradata/orcl/big_data01.dbf' SIZE 100G
AUTOEXTEND ON NEXT 10G MAXSIZE 30T;

对比 Smallfile 和 Bigfile

维度SmallfileBigfile
单文件最大4M 块(约 32GB)4G 块(约 32TB)
每表空间文件数多个一个
管理复杂简单
备份可并行单文件
性能多文件可分布单文件

9. 表空间相关视图

9.1 dba_tablespaces

SELECT tablespace_name, contents, status, 
       extent_management, allocation_type, 
       segment_space_management, bigfile
FROM dba_tablespaces;

9.2 dba_data_files

SELECT file_name, file_id, tablespace_name, 
       bytes/1024/1024 AS size_mb,
       autoextensible, maxbytes/1024/1024 AS max_mb,
       increment_by * 8192 / 1024 / 1024 AS increment_mb
FROM dba_data_files
ORDER BY tablespace_name;

9.3 dba_free_space

-- 查看表空间剩余空间
SELECT tablespace_name, 
       SUM(bytes)/1024/1024 AS free_mb,
       COUNT(*) AS free_extents
FROM dba_free_space
GROUP BY tablespace_name
ORDER BY free_mb;

9.4 dba_segments

-- 查看段
SELECT owner, segment_name, segment_type, 
       tablespace_name, bytes/1024/1024 AS size_mb
FROM dba_segments
WHERE tablespace_name = 'USERS'
ORDER BY bytes DESC;

9.5 v$tablespace

SELECT ts#, name, bigfile, included_in_database_backup
FROM v$tablespace;

9.6 综合查询:表空间使用情况

SELECT 
    a.tablespace_name,
    a.total_mb,
    NVL(b.used_mb, 0) AS used_mb,
    NVL(b.used_mb, 0) / a.total_mb * 100 AS used_pct,
    a.total_mb - NVL(b.used_mb, 0) AS free_mb
FROM (
    SELECT tablespace_name, SUM(bytes)/1024/1024 AS total_mb
    FROM dba_data_files
    GROUP BY tablespace_name
) a
LEFT JOIN (
    SELECT tablespace_name, SUM(bytes)/1024/1024 AS used_mb
    FROM dba_segments
    GROUP BY tablespace_name
) b
ON a.tablespace_name = b.tablespace_name
ORDER BY used_pct DESC;

10. 表空间管理操作

10.1 创建表空间

-- 标准 OLTP 表空间
CREATE TABLESPACE business_data
DATAFILE '/u01/oradata/orcl/business01.dbf' SIZE 1G
AUTOEXTEND ON NEXT 100M MAXSIZE 10G
EXTENT MANAGEMENT LOCAL AUTOALLOCATE
SEGMENT SPACE MANAGEMENT AUTO;

-- 多数据文件
CREATE TABLESPACE big_data
DATAFILE 
  '/u01/oradata/orcl/big01.dbf' SIZE 5G,
  '/u02/oradata/orcl/big02.dbf' SIZE 5G
AUTOEXTEND ON NEXT 500M MAXSIZE 50G
EXTENT MANAGEMENT LOCAL UNIFORM SIZE 1M;

-- 加密表空间(需先建 keystore)
CREATE TABLESPACE encrypted_data
DATAFILE '/u01/oradata/orcl/enc01.dbf' SIZE 1G
ENCRYPTION USING 'AES256'
DEFAULT STORAGE (ENCRYPT);

10.2 修改表空间

-- 重命名
ALTER TABLESPACE users RENAME TO app_data;

-- 只读
ALTER TABLESPACE users READ ONLY;

-- 可读写
ALTER TABLESPACE users READ WRITE;

-- 脱机
ALTER TABLESPACE users OFFLINE NORMAL;

-- 联机
ALTER TABLESPACE users ONLINE;

10.3 删除表空间

-- 仅删除表空间(保留数据文件,不推荐)
DROP TABLESPACE users;

-- 删除表空间和数据文件(推荐)
DROP TABLESPACE users INCLUDING CONTENTS AND DATAFILES;

-- 同时删除约束
DROP TABLESPACE users INCLUDING CONTENTS AND DATAFILES CASCADE CONSTRAINTS;

坑 2:删除表空间前必须确认无依赖对象。

10.4 数据文件管理

-- 添加数据文件
ALTER TABLESPACE users 
ADD DATAFILE '/u02/oradata/orcl/users02.dbf' 
SIZE 500M 
AUTOEXTEND ON NEXT 100M MAXSIZE 5G;

-- Bigfile 表空间 resize
ALTER TABLESPACE big_data RESIZE 200G;

-- 数据文件 resize
ALTER DATABASE DATAFILE '/u01/oradata/orcl/users01.dbf' 
RESIZE 1G;

-- 数据文件自动扩展
ALTER DATABASE DATAFILE '/u01/oradata/orcl/users01.dbf'
AUTOEXTEND ON NEXT 100M MAXSIZE 5G;

-- 数据文件重命名(需表空间脱机)
ALTER TABLESPACE users OFFLINE NORMAL;
-- OS 层 mv
ALTER TABLESPACE users RENAME DATAFILE 
  '/u01/oradata/orcl/users01.dbf'
TO '/u02/oradata/orcl/users01.dbf';
ALTER TABLESPACE users ONLINE;

11. 空间管理与碎片

11.1 高水位线(HWM)

HWM 标记段中曾经被使用过的最高数据块位置[1]。

段空间布局:
┌───────────────────────────────────────┐
│  已使用块    │   未使用块(HWM 以下)   │   HWM 以上未格式化
└───────────────────────────────────────┘
                ↑ HWM

全表扫描会扫描 HWM 以下所有块(即使空块)

查看 HWM

-- 表的 HWM
SELECT table_name, blocks, empty_blocks, num_rows
FROM dba_tables
WHERE table_name = 'YOUR_TABLE';

-- 实际使用情况
EXEC DBMS_STATS.GATHER_TABLE_STATS('SCOTT', 'EMP');
SELECT blocks, empty_blocks FROM dba_tables WHERE table_name='EMP';

坑 3:DELETE 数据不会降低 HWM,全表扫描仍扫描所有块。

11.2 段收缩(Segment Shrink)

收缩段可降低 HWM,回收空闲空间[2]:

-- 1. 启用行移动
ALTER TABLE scott.emp ENABLE ROW MOVEMENT;

-- 2. 收缩段(包含 HWM 调整)
ALTER TABLE scott.emp SHRINK SPACE;

-- 3. 仅整理碎片,不调整 HWM
ALTER TABLE scott.emp SHRINK SPACE COMPACT;

-- 4. 收缩并 CASCADE(含索引)
ALTER TABLE scott.emp SHRINK SPACE CASCADE;

-- 5. 重新收集统计信息
EXEC DBMS_STATS.GATHER_TABLE_STATS('SCOTT', 'EMP');

坑 4:段收缩会触发行迁移,影响期间性能,建议低峰执行。


12. 常见坑与排错

坑 1:ORA-01653 表空间不足

现象

ORA-01653: unable to extend table SCOTT.EMP by 128 in tablespace USERS

解决

-- 1. 查看表空间剩余空间
SELECT tablespace_name, SUM(bytes)/1024/1024 AS free_mb
FROM dba_free_space
WHERE tablespace_name = 'USERS'
GROUP BY tablespace_name;

-- 2. 添加数据文件
ALTER TABLESPACE users 
ADD DATAFILE '/u02/oradata/orcl/users02.dbf' 
SIZE 1G AUTOEXTEND ON NEXT 100M MAXSIZE 10G;

-- 3. 或 resize 现有文件
ALTER DATABASE DATAFILE '...' RESIZE 2G;

-- 4. 或启用自动扩展
ALTER DATABASE DATAFILE '...' AUTOEXTEND ON;

坑 2:ORA-01652 临时表空间不足

现象

ORA-01652: unable to extend temp segment by 128 in tablespace TEMP

解决

-- 添加临时文件
ALTER TABLESPACE temp 
ADD TEMPFILE '/u02/oradata/orcl/temp02.dbf' 
SIZE 2G AUTOEXTEND ON NEXT 100M MAXSIZE 10G;

坑 3:ORA-01688 表空间配额不足

现象

ORA-01688: table SCOTT.EMP partition P1 extended failed

原因:用户在表空间的配额已用尽。

解决

-- 查看用户配额
SELECT tablespace_name, bytes/1024/1024 AS used_mb, 
       max_bytes/1024/1024 AS max_mb
FROM dba_ts_quotas
WHERE username = 'SCOTT';

-- 增加配额
ALTER USER scott QUOTA UNLIMITED ON users;

坑 4:SYSTEM 表空间爆满

现象:SYSTEM 表空间使用率过高。

解决

-- 查看 SYSTEM 表空间中的非系统对象
SELECT owner, segment_name, segment_type, bytes/1024/1024 AS size_mb
FROM dba_segments
WHERE tablespace_name = 'SYSTEM'
  AND owner NOT IN ('SYS', 'SYSTEM', 'OUTLN', 'DBSNMP')
ORDER BY bytes DESC;

-- 迁移到其他表空间
ALTER TABLE scott.emp MOVE TABLESPACE users;
ALTER INDEX scott.emp_pk REBUILD TABLESPACE users;

坑 5:表空间碎片严重

现象:表空间剩余空间足够,但仍报 ORA-01653。

诊断

-- 查看碎片程度
SELECT tablespace_name, 
       COUNT(*) AS free_extents,
       MAX(bytes)/1024/1024 AS max_free_mb,
       SUM(bytes)/1024/1024 AS total_free_mb
FROM dba_free_space
GROUP BY tablespace_name;
-- free_extents 多但 max_free_mb 小 = 碎片严重

解决

  • 用 LMT + UNIFORM 避免碎片
  • 段收缩
  • 表空间重组(exp/imp 或 data pump)

坑 6:数据文件损坏

现象

ORA-01115: IO error reading block from file  (block # )
ORA-01110: data file 4: '/u01/oradata/orcl/users01.dbf'

解决

-- 1. 查看损坏数据文件
SELECT file#, status, name FROM v$datafile WHERE file# = 4;

-- 2. 脱机
ALTER DATABASE DATAFILE 4 OFFLINE;

-- 3. RMAN 恢复
rman target /
RMAN> RESTORE DATAFILE 4;
RMAN> RECOVER DATAFILE 4;

-- 4. 联机
ALTER DATABASE DATAFILE 4 ONLINE;

坑 7:表空间 OFFLINE 后无法 ONLINE

现象

ORA-01113: file 4 needs media recovery

解决

-- 需要先恢复
RECOVER DATAFILE 4;
ALTER DATABASE DATAFILE 4 ONLINE;

坑 8:HWM 过高导致查询慢

现象:表数据不多,但查询慢。

诊断

SELECT table_name, num_rows, blocks, 
       num_rows / NULLIF(blocks, 0) AS rows_per_block
FROM dba_tables
WHERE table_name = 'YOUR_TABLE';
-- rows_per_block 远小于正常值(通常 50-200)说明 HWM 过高

解决

-- 段收缩
ALTER TABLE your_table ENABLE ROW MOVEMENT;
ALTER TABLE your_table SHRINK SPACE;

-- 或重建表
ALTER TABLE your_table MOVE TABLESPACE users;

13. 最佳实践

  1. 使用 LMT + ASSM:Oracle 10g+ 默认,避免碎片和并发问题[2]
  2. 业务数据独立表空间:避免放 SYSTEM
  3. 数据文件 AUTOEXTEND ON:避免 ORA-01653
  4. 设置 MAXSIZE:避免撑爆磁盘
  5. 数据文件分散在不同磁盘:I/O 负载均衡
  6. TEMP 表空间适当大:避免排序失败
  7. UNDO 表空间适当大:避免 ORA-01555
  8. 定期监控使用率:阈值 80%
  9. 生产环境避免 DMT:已废弃
  10. Bigfile 仅在超大表空间使用:单文件管理简单
  11. 段收缩降低 HWM:定期执行
  12. 批量加载后立即收集统计:避免 CBO 决策错误
  13. 表空间加密保护敏感数据:金融、医疗场景
  14. 大表用分区表:跨多个表空间
  15. SYSTEM 表空间只放系统对象:业务对象迁移出去

14. 参考资料

[1] Oracle Database 19c Concepts,Logical Storage Structures: https://docs.oracle.com/en/database/oracle/oracle-database/19/cncpt/logical-storage-structures.html

[2] CSDN,《微观世界的层级之美:深度解析 Oracle 数据块、区(Extent)与段(Segment)的层级关系》: https://blog.csdn.net/qq_41840843/article/details/162770757

[3] CSDN,《深入探索 Oracle 数据库空间管理与监控》: https://blog.csdn.net/qq_36936192/article/details/155457150

[4] Oracle Database 19c Administrator’s Guide,Managing Tablespaces: https://docs.oracle.com/en/database/oracle/oracle-database/19/admin/managing-tablespaces.html

[5] Oracle Database 19c Concepts,Physical Storage Structures: https://docs.oracle.com/en/database/oracle/oracle-database/19/cncpt/physical-storage-structures.html

[6] GBASE 数据库,《南大通用 GBase 8s 数据库与 Oracle 存储结构对照简析》: http://m.toutiao.com/group/7664867784794325538/

[7] Oracle Database 19c Administrator’s Guide,Bigfile Tablespaces: https://docs.oracle.com/en/database/oracle/oracle-database/19/admin/managing-tablespaces.html#GUID-3F8A6F3B-78D2-4D67-9F12-2B5B6F8B5E26


相关文章