创建表空间
- EXTENT MANAGEMENT LOCAL 是 9i 之后的默认且推荐方式
- SEGMENT SPACE MANAGEMENT AUTO 用位图管理,比手动管理更高效
- AUTOEXTEND 要设 MAXSIZE,否则可能把磁盘写满导致实例挂起
- 本地管理的表空间用 AUTOALLOCATE(由系统决定区大小)或 UNIFORM(所有区统一大小)管理区;只有 UNIFORM 才需要你指定统一的区大小
-- 小文件表空间(默认类型,可包含多个数据文件)
CREATE TABLESPACE app_data
DATAFILE 'app_data01.dbf'
SIZE 100M
AUTOEXTEND ON NEXT 50M MAXSIZE 2G
EXTENT MANAGEMENT LOCAL -- 本地管理,现代默认
SEGMENT SPACE MANAGEMENT AUTO;
-- 自动段空间管理
-- 大文件表空间:只能有 1 个数据文件,但该文件可以极大
-- 8KB 块下单文件上限约 32TB(2^32 个块)
CREATE BIGFILE TABLESPACE app_big
DATAFILE 'app_big01.dbf'
SIZE 1G
AUTOEXTEND ON NEXT 100M;CREATE TABLESPACE 需要 DBA 权限,普通用户执行会报 ORA-01031。另外 DATAFILE 只写裸文件名时,实际路径由初始化参数 DB_CREATE_FILE_DEST 决定(OMF);没配这个参数就必须写完整路径。后续要 RESIZE 时,路径必须与控制文件里登记的一致。
只作示例阅读:建/改用户、角色、表空间。请在独立学习数据库中练习。
查看空间使用
SELECT d.tablespace_name,
ROUND(d.total_mb, 2) AS total_mb,
ROUND(NVL(f.free_mb, 0), 2) AS free_mb,
ROUND(d.total_mb - NVL(f.free_mb, 0), 2) AS used_mb,
ROUND((d.total_mb - NVL(f.free_mb, 0)) / d.total_mb * 100, 2) AS used_pct
FROM (SELECT tablespace_name, SUM(bytes)/1024/1024 AS total_mb
FROM dba_data_files GROUP BY tablespace_name) d
LEFT JOIN (SELECT tablespace_name, SUM(bytes)/1024/1024 AS free_mb
FROM dba_free_space GROUP BY tablespace_name) f
ON f.tablespace_name = d.tablespace_name
ORDER BY used_pct DESC;只作示例阅读:读取全库字典或会话(沙箱只开放自身对象)。请在独立学习数据库中练习。
SELECT owner, segment_name, segment_type,
ROUND(bytes/1024/1024, 2) AS mb
FROM dba_segments
WHERE tablespace_name = 'USERS'
ORDER BY bytes DESC
FETCH FIRST 15 ROWS ONLY;只作示例阅读:读取全库字典或会话(沙箱只开放自身对象)。请在独立学习数据库中练习。
扩容与常见报错
- ORA-01652: unable to extend ... → 某个段无法在指定表空间内扩展。segment_type 可能是 temporary、table、index、LOB 等,永久表空间不足同样会报这个错
- ORA-01653: unable to extend table → 表无法在表空间内扩展,通常是表空间满了
- ORA-01654: unable to extend index → 索引无法扩展,通常是索引所在表空间满了
- 处理前先看报错里的 segment_type 与 tablespace_name,确认是临时还是永久表空间,两者做法不同
-- 1) 给已有数据文件加大
-- 注意:这里必须写控制文件中登记的实际路径,或直接用 file#;
-- 只写裸文件名会报 ORA-01516(指定的文件不存在)
ALTER DATABASE DATAFILE '/u01/oradata/ORCL/app_data01.dbf' RESIZE 500M;
-- 用编号更省事,file# 查 v$datafile
ALTER DATABASE DATAFILE 5 RESIZE 500M;
-- 2) 打开自动扩展
ALTER DATABASE DATAFILE '/u01/oradata/ORCL/app_data01.dbf'
AUTOEXTEND ON NEXT 100M MAXSIZE 4G;
-- 3) 新增数据文件
ALTER TABLESPACE app_data
ADD DATAFILE '/u01/oradata/ORCL/app_data02.dbf' SIZE 200M
AUTOEXTEND ON NEXT 100M MAXSIZE 4G;查询实际文件路径:SELECT file#, name FROM v$datafile;(或 dba_data_files)。
只作示例阅读:改数据库/实例参数。请在独立学习数据库中练习。
段、区、块
- 数据块(Block):I/O 的最小单位,由 DB_BLOCK_SIZE 决定,建库后不可改
- 区(Extent):连续数据块的集合,是空间分配的单位
- 段(Segment):一个区以上的集合,对应一个表、索引或分区等对象
- ASSM(自动段空间管理)用位图跟踪块的使用状态,避免手工调整 FREELIST
- 高水位线(HWM):段中已使用过的块上限;DELETE 不会降低它,所以删数据不释放空间,需要 SHRINK 或 MOVE
-- 允许行移动,然后收缩
ALTER TABLE employees_demo ENABLE ROW MOVEMENT;
ALTER TABLE employees_demo SHRINK SPACE CASCADE;
-- CASCADE 连带收缩索引
-- 或者更彻底:MOVE 重建
-- 先建个索引,好观察 MOVE 之后索引的状态
CREATE INDEX idx_demo_salary ON employees_demo (salary);
-- 不带 TABLESPACE 就是搬到当前表空间,避免依赖某个特定表空间是否存在
ALTER TABLE employees_demo MOVE;
-- MOVE 会让表上的原有索引全部变为 UNUSABLE,必须重建
-- 索引名请用实际存在的,可先查:
-- SELECT index_name, status FROM user_indexes WHERE table_name = 'EMPLOYEES_DEMO';
ALTER INDEX idx_demo_salary REBUILD;只作示例阅读:5 行写入限制下只开放单独创建普通空表;CTAS、删表、清空表、改结构、触发器和存储程序不允许执行。请在独立学习数据库中练习。