Oracle表空间不足导致写入失败,90%是表空间逻辑耗尽而非磁盘满;须查dba_free_space确认真实使用率(≥95%即告急),检查autoextensible状态及用户配额,优先新增数据文件扩容。

Oracle表空间不足导致写入失败,90% 的情况不是磁盘满,而是表空间本身已无可用空闲区(extent),INSERT、UPDATE 或 DDL 操作直接报 ORA-01653、ORA-01654 或 ORA-01683。必须先确认是表空间逻辑空间耗尽,而非操作系统层磁盘写满。
查表空间真实使用率,别信 df -h
OS 层 df -h 显示磁盘还有 40% 空间,不代表 Oracle 能用——表空间可能早已 100% 占用。关键看 dba_free_space,它反映的是已格式化、可分配的空闲块:
- 运行:
SELECT tablespace_name, ROUND((SUM(bytes) - NVL(SUM(free_bytes), 0)) / SUM(bytes) * 100, 2) used_pct FROM (SELECT tablespace_name, SUM(bytes) bytes FROM dba_data_files GROUP BY tablespace_name) a LEFT JOIN (SELECT tablespace_name, SUM(bytes) free_bytes FROM dba_free_space GROUP BY tablespace_name) b ON a.tablespace_name = b.tablespace_name WHERE a.tablespace_name = 'YOUR_TS' GROUP BY a.tablespace_name; - 若
used_pct ≥ 95%,基本锁定问题根源;特别注意SYSTEM表空间,Navicat 导入 DDL 时默认建临时对象,容易撑爆它 -
dba_free_space不包含刚扩容但尚未格式化的空间(即AUTOEXTEND新增部分还没被 Oracle 分配为可用 extent),所以“有 free space”不等于“能立刻分配”
检查数据文件 autoextensible 是否真开启
很多 DBA 以为开了 AUTOEXTEND 就万事大吉,但实际常被设为 NO 或 MAXSIZE 已到顶:
- 查状态:
SELECT file_name, autoextensible, maxbytes/1024/1024 max_mb FROM dba_data_files WHERE tablespace_name = 'YOUR_TS'; -
autoextensible = 'NO'是高频原因——即使磁盘还有空间,Oracle 绝对不会扩展文件 -
max_mb接近文件系统剩余空间(如显示32768MB 而df -h显示挂载点只剩 30G),说明已达上限,AUTOEXTEND ON形同虚设 -
increment_by单位是 Oracle 块数(非 KB/M),默认db_block_size=8192,所以increment_by=64000实际增长 500MB,别误判为只增 64KB
扩容优先选加文件,慎用 resize
单个数据文件扩到极限(尤其 Windows 下 32GB 小文件表空间)会触发 ORA-01144,且 resize 存在风险:
- 已有数据的文件,
ALTER DATABASE DATAFILE '/path/file.dbf' RESIZE 20G若当前文件 >20G,直接报错;若小于 20G,则强制截断——**必然丢失末尾数据** - 更稳妥做法是新增文件:
ALTER TABLESPACE YOUR_TS ADD DATAFILE '/new/path/file02.dbf' SIZE 2G AUTOEXTEND ON NEXT 512M MAXSIZE 30G; - 多个小文件比单个超大文件更利于 I/O 均衡,也规避单点故障;新文件路径权限必须为
oracle:oinstall,父目录至少r-x权限 - 若用 ASM,路径必须是
+DATA/PROD/DATAFILE/xxx.dbf,不能填本地路径
临时表空间和 UNDO 表空间不能套用同一套逻辑
TEMP 和 UNDOTBS1 的扩容机制与普通表空间完全不同:
-
TEMP表空间满通常因排序操作未释放,SELECT * FROM v$sort_segment;查活跃临时段;重启实例可清空,但生产环境不推荐;更安全的是添加新临时文件:ALTER TABLESPACE TEMP ADD TEMPFILE '/u01/oradata/ORCL/temp02.dbf' SIZE 2G; -
UNDOTBS1不能直接ADD DATAFILE,需调整UNDO_RETENTION参数或增大现有文件:ALTER DATABASE DATAFILE '/u01/oradata/ORCL/undotbs01.dbf' RESIZE 4G;,但前提是 undo 表空间为AUTOEXTEND OFF且未达最大限制 - 这两类表空间的告警日志里常出现
ORA-01555或ORA-01652,和ORA-01653的根因不同,不能混查dba_free_space
最易被忽略的点:用户默认表空间配额(quota)为 0 或过小,即使表空间有空间,INSERT 仍会失败;执行 SELECT username, default_tablespace, temporary_tablespace FROM dba_users WHERE username = 'YOUR_USER'; 后,再查 SELECT * FROM dba_ts_quotas WHERE username = 'YOUR_USER'; ——配额不足时,ALTER USER your_user QUOTA UNLIMITED ON your_ts; 才是解法。


















